题目大意
给定一些点,每个点的值为距离它最近的1的点的曼哈顿距离,求出所有点与它周边不超过 行 列的值
解题思路
首先我们看到这题的数据范围,用黄*邦想都知道这是一个
能过的题,所以我就
乱打了一个广搜,然后用前缀和
维护一下行列就过了。
还有一种是用前缀和维护矩阵,好像是
,只能%一%,然后就直接扣代码了
代码
SRC Download
#include<queue>
#include<cstdio>
#include<algorithm>
#define r(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;int t,n,r,s[151][151],a[151][151],ans;
const short dx[4]={-1,0,1,0};
const short dy[4]={0,1,0,-1};
bool d[151][151];
struct node{int x,y,s;};
int bfs(node start)
{
if(d[start.x][start.y]) return 0;
queue<node>q;bool vis[151][151]={0};
q.push(start);vis[start.x][start.y]=true;
while(q.size())
{
node x=q.front();q.pop();
r(i,0,3)
{
node y=(node){x.x+dx[i],x.y+dy[i],x.s+1};
if(y.x<1||y.y<1||y.x>n||y.y>n) continue;
if(vis[y.x][y.y]) continue;
if(d[y.x][y.y]) return y.s;
q.push(y);
vis[y.x][y.y]=true;
}
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&r);
r(i,1,n) r(j,1,n) scanf("%d",&d[i][j]);
r(i,1,n) r(j,1,n) a[i][j]=bfs((node){i,j,0}),s[i][j]=s[i][j-1]+a[i][j];//前缀和维护
r(i,1,n)
{
r(j,1,n)
{
ans=0;
r(k,max(i-r,0),min(i+r,n)) ans+=s[k][min(j+r,n)]-s[k][max(j-r-1,0)];
printf("%d ",ans);
}
putchar(10);
}
putchar(10);
}
}
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
queue<int>x,y;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
int f[151][151],ans[151][151],c[151][151];
int n;
void bfs()
{
while(!x.empty())
{
for(int i=0;i<4;i++)
{
int xx=x.front()+dx[i],yy=y.front()+dy[i];
if(xx<1||yy<1||xx>n||yy>n||c[xx][yy]==1) continue;
c[xx][yy]=1;
f[xx][yy]=f[x.front()][y.front()]+1;
x.push(xx);y.push(yy);
}
x.pop();y.pop();
}
return;
}
int main()
{
int t=read(),a,bx,by,sx,sy;
for(int i=1;i<=t;i++)
{
memset(f,0,sizeof(f));
memset(ans,0,sizeof(ans));
n=read();int r=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
c[i][j]=read();
if(c[i][j]) x.push(i),y.push(j);
}
bfs();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ans[i][j]=ans[i-1][j]+ans[i][j-1]+f[i][j]-ans[i-1][j-1];//前缀和维护
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
bx=min(n,i+r);by=min(n,j+r);
sx=max(0,i-r-1);sy=max(0,j-r-1);
printf("%d ",ans[bx][by]-ans[bx][sy]-ans[sx][by]+ans[sx][sy]);
}
printf("\n");
}
printf("\n");
}
return 0;
}