Description
中山市的地图是一个n*n的矩阵,其中标号为1的表示商业区,标号为0的表示居民区。为了考察市内居民区与商业区的距离,并对此作出评估,市长希望你能够编写一个程序完成这一任务。
居民区i到商业区的距离指的是到距离它最近的商业区j的距离(|Xi-Xj|+|Yi-Yj|),而你将统计的是对于城市中的每一个区域k,以它为中心,所有满足max(|Xk-Xm|,|Yk-Ym|)<=r的区域m到商业区距离之和。结果同样以n*n的矩阵形式输出。
居民区i到商业区的距离指的是到距离它最近的商业区j的距离(|Xi-Xj|+|Yi-Yj|),而你将统计的是对于城市中的每一个区域k,以它为中心,所有满足max(|Xk-Xm|,|Yk-Ym|)<=r的区域m到商业区距离之和。结果同样以n*n的矩阵形式输出。
Input
第一行为t,表示以下有t组数据,每组数据之间以空行隔开,以下:
第一行为n,r(1<=r<n<=150)
第二行起为一个n*n的矩阵。
第一行为n,r(1<=r<n<=150)
第二行起为一个n*n的矩阵。
Output
t组n*n的矩阵。每组用空行隔开
Sample Input
Sample Input1:
1
4 1
1 0 0 0
1 1 0 0
0 1 1 0
0 1 0 0
Sample Input2:
2
10 4
1 0 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 0 0 1 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 1 0 0 1 0 0 0
0 0 1 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0 0 1
10 9
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
Summary
先用bfs算出每个居民区距离最近商业区的距离,再求二位前缀和:f[j][k]=f[j][k]-f[j-1][k-1]+f[j-1][k]+f[j][k-1]
那么以(k,j)为中心,边为2*e正方形的值为:f[min(m,j+e)][min(m,k+e)]+f[max(0,j-e-1)][max(0,k-e-1)]-f[min(m,j+e)][max(0,k-e-1)]-f[max(0,j-e-1)][min(m,k+e)]
注意边界范围
Code

1 #include<cstdio> 2 using namespace std; 3 int t,m,l[4],r[4],a[200][200],f[200][200],dy[1000000][2],e; 4 int max(int x,int y) 5 { 6 if (x>y) return x; 7 return y; 8 } 9 int min(int x,int y) 10 { 11 if (x>y) return y; 12 return x; 13 } 14 int main() 15 { 16 l[1]=0;l[2]=0;l[3]=1;l[4]=-1; 17 r[1]=1;r[2]=-1;r[3]=0;r[4]=0; 18 scanf("%d",&t); 19 for (int i=1;i<=t;i++) 20 { 21 int tot=0,ans=1; 22 scanf("%d%d",&m,&e); 23 for (int j=1;j<=m;j++) 24 for (int k=1;k<=m;k++) 25 f[j][k]=0xffffff; 26 for (int j=1;j<=m;j++) 27 for (int k=1;k<=m;k++) 28 { 29 scanf("%d",&a[j][k]); 30 if (a[j][k]==1) 31 { 32 tot++; 33 dy[tot][1]=j; 34 dy[tot][2]=k; 35 f[j][k]=0; 36 } 37 } 38 while (ans<=tot) 39 { 40 for (int j=1;j<=4;j++) 41 { 42 int z=dy[ans][1]+l[j],g=dy[ans][2]+r[j]; 43 if (z>=1&&g>=1&&z<=m&&g<=m) 44 if (f[z][g]>f[dy[ans][1]][dy[ans][2]]+1) 45 { 46 f[z][g]=f[dy[ans][1]][dy[ans][2]]+1; 47 tot++; 48 dy[tot][1]=z; 49 dy[tot][2]=g; 50 } 51 } 52 ans++; 53 } 54 for (int j=1;j<=m;j++) 55 for (int k=1;k<=m;k++) 56 f[j][k]=f[j][k]-f[j-1][k-1]+f[j-1][k]+f[j][k-1]; 57 for (int j=1;j<=m;j++) 58 { 59 for (int k=1;k<=m;k++) 60 printf("%d ",f[min(m,j+e)][min(m,k+e)]+f[max(0,j-e-1)][max(0,k-e-1)]-f[min(m,j+e)][max(0,k-e-1)]-f[max(0,j-e-1)][min(m,k+e)]); 61 printf(" "); 62 } 63 printf(" "); 64 } 65 }