力扣LCP74.最强祝福力场
-
差分 + 离散化
- 先将所有正方形的左上角和右下角放入数组并排序**(2保证没有小数)*
- 二分得到新的坐标
- 在新坐标上做差分
-
class Solution { public: int fieldOfGreatestBlessing(vector<vector<int>>& forceField) { vector<long long> xs,ys; //xy存起来 for(auto &f:forceField) { long long i = f[0],j = f[1],side = f[2]; xs.push_back(2 * i - side); xs.push_back(2 * i + side); ys.push_back(2 * j - side); ys.push_back(2 * j + side); } //排序去重 ranges::sort(xs); xs.erase(unique(xs.begin(),xs.end()),xs.end()); ranges::sort(ys); ys.erase(unique(ys.begin(), ys.end()), ys.end()); int n = xs.size(),m = ys.size(),dif[n+2][m+2]; memset(dif,0,sizeof(dif)); //离散化 + 差分 for(auto &f:forceField) { long long i = f[0],j = f[1],side = f[2]; int r1 = lower_bound(xs.begin(),xs.end(),2 * i - side) - xs.begin(); int r2 = lower_bound(xs.begin(),xs.end(),2 * i + side) - xs.begin(); int c1 = lower_bound(ys.begin(), ys.end(), 2 * j - side) - ys.begin(); int c2 = lower_bound(ys.begin(), ys.end(), 2 * j + side) - ys.begin(); //+1方便求前缀和 r1 += 1,r2 += 1,c1 += 1,c2 += 1; dif[r1][c1] ++; dif[r1][c2+1] --; dif[r2+1][c1] --; dif[r2+1][c2+1] ++; } int ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { dif[i][j] += dif[i-1][j] + dif[i][j-1] - dif[i-1][j-1]; ans = max(ans,dif[i][j]); } return ans; } };