AcWing 3412. 邻域均值
原题链接
简单
作者:
xz_62
,
2024-09-28 22:46:53
,
所有人可见
,
阅读 3
差分解法
- 首先如果A在B邻域内,B一定在A邻域内。
- 对于每个点,我们去统计一个值
ans
:对于其邻域内每一个点的值x
,ans+=t-x
。最后如果ans>=0
,对应的点就是暗点。
- 实际操作中,我们每遍历一个点,就去更新其邻域内所有点的
ans
值,这里可以用二维差分优化(每个点的邻域范围是一个矩形,要把范围内每个点加上t-a[i][j]
)。
- 最后统计所有点中
ans>=0
的个数 。
#include <bits/stdc++.h>
using namespace std;
int n,l,r,t;
const int N=605;
int d[N][N];
int ans[N][N];
int getLRange(int x){return max(0,x-r);}
int getRRange(int x){return min(n-1,x+r);}
void work() {
cin>>n>>l>>r>>t;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
int x;
cin>>x;
int x1=getLRange(i),y1=getLRange(j);
int x2=getRRange(i),y2=getRRange(j);
int m=t-x;
d[x1][y1]+=m;
d[x2+1][y2+1]+=m;
d[x1][y2+1]-=m;
d[x2+1][y1]-=m;
}
//根据差分求结果
ans[0][0]=d[0][0];
for(int i=1;i<n;i++){
ans[i][0]=d[i][0]+ans[i-1][0];
ans[0][i]=d[0][i]+ans[0][i-1];
}
for(int i=1;i<n;i++)
for(int j=1;j<n;j++){
ans[i][j]=d[i][j]+ans[i][j-1]+ans[i-1][j]-ans[i-1][j-1];
}
int cnt=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if(ans[i][j]>=0) cnt++;
}
cout<<cnt;
}
int main() {
work();
return 0;
}