题目链接:
D-异或炸弹(easy)_牛客小白月赛95 (nowcoder.com)
题目:
题目分析:
一看 还以为是二维差分的题呢 到后来才发现是一维差分问题
这里的距离是 曼哈顿距离 dis = abs(x - xi) + abs(y - yi) 暴力的做法 就是枚举 n * n 个点 然后看看这n * n 个点到m次询问的点的距离是否小于等于r 但是时间复杂度为O(n *n * m )太高了 一定会TLE的其实发现 在每一行里面 满足的都是一段连续的 那么差分就排上用场了 a[l] ++, a[r + 1] --
枚举每一行 也就是定一个x 那么y的范围也就出来了 因为 abs(x - xi) + abs(y - yi) <= r 那么 y 的范围就是 yi - 剩余的(r - x到xi的距离) 到 yi + 剩余的(r - x到xi的距离) 这个y 就可以用差分去解决 注意边界问题 以及绝对值
需要注意的是 下面的代码里面的一个边界 a[i][min(n + 1, y + dis + 1)] -- ; 注意是 n + 1 要是写成 n 的话 表示的意思 就是 y为n的这个点 就永远取不到了 细节问题
代码:
#include<bits/stdc++.h>
#define y1 Y1
#define fi first
#define endl "\n"
#define se second
#define PI acos(-1)
#define int long long
#define pb(x) push_back(x)
#define PII pair<int, int>
#define Yes cout << "Yes\n";
#define No cout << "No\n";
#define YES cout << "YES\n";
#define NO cout << "NO\n";
#define _for(i, a, b) for(int i = a; i <= b; ++i)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;const int N = 3000 + 10;
const int mod = 1e9 + 7;int a[N][N];
int n, m, t, ret;
string s;signed main() {IOS;cin >> n >> m;while(m -- ) {int x, y, r;cin >> x >> y >> r;// 这里用的还是一维的差分的知识for(int i = max(1ll, x - r); i <= min(n, r + x); i ++ ) {int dis = r - abs(x - i); // 只要y在这个范围内就可以a[i][max(1ll, y - dis)] ++ ;a[i][min(n + 1, y + dis + 1)] -- ; } }for(int i = 1; i <= n; i ++ ) {t = 0;for(int j = 1; j <= n; j ++ ) {t += a[i][j];if(t % 2 == 1)ret ++ ;}}cout << ret << endl;return 0;
}