激光炸弹
地图上有 个目标,用整数
表示目标在地图上的位置,每个目标都有一个价值
。
注意:不同目标可能在同一位置。
现在有一种新型的激光炸弹,可以摧毁一个包含 个位置的正方形内的所有目标。
激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆炸范围,即那个正方形的边必须和 轴平行。
求一颗炸弹最多能炸掉地图上总价值为多少的目标。
输入格式
第一行输入正整数 和
,分别代表地图上的目标数目和正方形的边长,数据用空格隔开。
接下来 行,每行输入一组数据,每组数据包括三个整数
,分别代表目标的
坐标,
坐标和价值,数据用空格隔开。
输出格式
输出一个正整数,代表一颗炸弹最多能炸掉地图上目标的总价值数目。
数据范围,
输入样例:
2 10 0 11 1 1
输出样例:
1
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N = 10010, M = 5050;int n, r, x, y, w;int s[M][M];int get(int x, int y, int x0, int y0) {return s[x0][y0] - s[x0][y-1] - s[x-1][y0] + s[x-1][y-1];}int main(){scanf("%d%d", &n, &r);int mx = 0, my = 0;for(int i=1;i<=n;i++){scanf("%d%d%d", &x, &y, &w);x ++; y ++;mx = max(mx, x); my = max(my, y);s[x][y] += w;}for(int i=1;i<=mx;i++) for(int j=1;j<=my;j++) s[i][j] += s[i-1][j] + s[i][j-1] - s[i-1][j-1];int rs = 0;for(int i=1;i<=mx;i++) for(int j=1;j<=my;j++){int x = max(1, i - r + 1), y = max(1, j - r + 1);rs = max(rs, get(x, y, i, j));}printf("%d\n", rs);return 0;}
增减序列
给定一个长度为 的数列
,每次可以选择一个区间
,使下标在这个区间内的数都加一或者都减一。
求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
输入格式
第一行输入正整数 。
接下来 行,每行输入一个整数,第
行的整数代表
。
输出格式
第一行输出最少操作次数。
第二行输出最终能得到多少种结果。
数据范围,
输入样例:
41122
输出样例:
12
此题是 铺设道路 的进阶版。
设 a 序列的差分序列为 b 序列。那么一次a区间加或者区间减对应b数组中的两个单点运算。
b[i] = a[i] - a[i-1],那么应当有
- 区间加:
- 区间减:
所以,只要计算出 中正数的和 p 以及 负数的绝对值和 q,就可以得到答案。
当然 p 和 q 的数量可能不同,设 x = abs(p - q),那么这 x 次区间操作,可以选择一部分修改 b[1], 也可以修改 b[n + 1]。
不难想到,最少操作数是 max(p, q)。
如果选择修改 b[1],则相当于改变最终数组中所有数值的大小。所以共有 x + 1 种方案。
#include <bits/stdc++.h>using namespace std;const int N = 100010;typedef long long ll;int n;ll a[N];int main(){scanf("%d", &n);for(int i=1;i<=n;i++) scanf("%lld", &a[i]);ll p = 0, q = 0;for(int i=2;i<=n;i++){ll c = a[i] - a[i-1];if(c > 0) p += c;else q -= c;}ll rs1 = max(p, q), rs2 = abs(p - q) + 1;printf("%lld\n%lld\n", rs1, rs2);return 0;}
最高的牛
有 头牛站成一行,被编队为
,每头牛的身高都为整数。
当且仅当两头牛中间的牛身高都比它们矮时,两头牛方可看到对方。
现在,我们只知道其中最高的牛是第 头,它的身高是
,剩余牛的身高未知。
但是,我们还知道这群牛之中存在着 对关系,每对关系都指明了某两头牛
和
可以相互看见。
求每头牛的身高的最大可能值是多少。
输入格式
第一行输入整数 ,数据用空格隔开。
接下来 行,每行输出两个整数
和
,代表牛
和牛
可以相互看见,数据用空格隔开。
输出格式
一共输出 行数据,每行输出一个整数。
第 行输出的整数代表第
头牛可能的最大身高。
数据范围,
,
,
输入样例:
9 3 5 51 35 34 33 79 8
输出样例:
545344555
此题中给出的关系对可能存在重复
首先忽略掉第 p 头牛的身高 H,仅仅计算每头牛的身高差。
如果存在一对关系 ,那么 c[a + 1] —, c[b] ++。
最后所有的 c 应当加上 h - c[p]。
输入时,关系会重复出现,所以要去重。
#include<bits/stdc++.h>using namespace std;#define rep(i,j,k) for(int i=int(j);i<=int(k);i++)#define per(i,j,k) for(int i=int(j);i>=int(k);i--)typedef long long ll;const int N = 10010;int n, p, h, m;int c[N];unordered_map<int, int> mp;int main(){scanf("%d%d%d%d", &n, &p, &h, &m);rep(i,1,m) {int a, b;scanf("%d%d", &a, &b);if(a > b) swap(a, b);int x = a * 10000 + b;if(mp.count(x)) continue;mp[x] = 1;c[a + 1] --; c[b] ++;}rep(i,1,n) c[i] += c[i-1];int x = h - c[p];rep(i,1,n) c[i] += x;rep(i,1,n) printf("%d\n",c[i]);return 0;}
