好久没写博客了,今天有空写一下。
题目描述
中山市的地图是一个 n ∗ n n*n n∗n的矩阵,其中标号为1的表示商业区,标号为0的表示居民区。为了考察市内居民区与商业区的距离,并对此作出评估,市长希望你能够编写一个程序完成这一任务。 居民区i到商业区的距离指的是到距离它最近的商业区j的距离 ( ∣ X i − X j ∣ + ∣ Y i − Y j ∣ ) (|Xi-Xj|+|Yi-Yj|) (∣Xi−Xj∣+∣Yi−Yj∣)(你可以理解为他们的行列分别作差),而你将统计的是对于城市中的每一个区域k,以它为中心的 ( 2 ∗ r + 1 ) ∗ ( 2 ∗ r + 1 ) (2*r+1)*(2*r+1) (2∗r+1)∗(2∗r+1)的矩阵区域内所有居民区到商业区的距离总和。结果同样以n*n的矩阵形式输出。
输入
第一行为t,表示以下有t组数据,每组数据之间以空行隔开,以下:
第一行为
n
,
r
(
1
<
=
r
<
n
<
=
150
)
n,r(1<=r<n<=150)
n,r(1<=r<n<=150)
第二行起为一个
n
∗
n
n*n
n∗n的矩阵。
输出
t t t组 n ∗ n n*n n∗n的矩阵。每组用空行隔开
样例输入
1
4 1
1 0 0 0
1 1 0 0
0 1 1 0
0 1 0 0
样例输出
1 4 9 8
2 5 10 9
2 4 7 7
2 3 4 4
题目大意:
有 n 2 n^2 n2大小的方阵,有 0 0 0和 1 1 1,求出没个 0 0 0距离他最近的 1 1 1的曼哈顿距离,统计的是对于每一个区域 k k k,以它为中心的 ( 2 ∗ r + 1 ) ∗ ( 2 ∗ r + 1 ) (2*r+1)*(2*r+1) (2∗r+1)∗(2∗r+1)的矩阵区域内所有 0 0 0到 1 1 1的距离总和。结果同样以 n 2 n^2 n2的矩阵形式输出。
思路:
60~70分:
直接爆力枚举每一个
0
0
0到1的距离,再暴力枚举出
(
2
∗
r
+
1
)
∗
(
2
∗
r
+
1
)
(2*r+1)*(2*r+1)
(2∗r+1)∗(2∗r+1)的矩阵,输出。
时间复杂度:
O
(
n
4
)
O(n^4)
O(n4)
100分:
考虑宽搜,先把
1
1
1放进队列,在扩展。最后再用二维前缀和算出
(
2
∗
r
+
1
)
∗
(
2
∗
r
+
1
)
(2*r+1)*(2*r+1)
(2∗r+1)∗(2∗r+1)的矩阵,输出。
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
代码:
#include<bits/stdc++.h> //码风已毒瘤,勿喷
#define INF 0x7ffffff
#define rg register
#define F(i,a,b,c) for(rg int i=(a);i<=(b);i+=(c))
#define Fu(i,a,b) F(i,a,b,1)
#define Fd(i,a,b) for(rg int i=(a);i>=(b);i--)
#define clear(x) memset(x,0,sizeof(x))
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define close() fclose(stdin),fclose(stdout)
using namespace std;
int t,n,ri,a[155][155],f[155][155],sum[155][155],bj[155][155],q[100005][3],l,r;
int way[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
int main() {
fre(city);
scanf("%d",&t);
Fu(k,1,t){
clear(f),clear(sum),clear(bj),clear(q),l=r=0;
scanf("%d%d",&n,&ri);
Fu(i,1,n){
Fu(j,1,n){
scanf("%d",&a[i][j]);
if(a[i][j]==1)
q[++r][1]=i,q[r][2]=j,bj[i][j]=1;
}
}
while(l<r){
l++;
Fu(i,0,3){
int xx=q[l][1]+way[i][0],yy=q[l][2]+way[i][1];
if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&bj[xx][yy]==0){
r++;
bj[xx][yy]=1;
f[xx][yy]=q[l][0]+1,q[r][0]=q[l][0]+1,q[r][1]=xx,q[r][2]=yy;
}
}
}
Fu(i,1,n){
int u=0;
Fu(j,1,n){
u+=f[i][j];
sum[i][j]=sum[i-1][j]+u;
}
}
Fu(i,1,n){
Fu(j,1,n){
int a=max(i-ri,1),b=max(j-ri,1),aa=min(i+ri,n),bb=min(j+ri,n);
printf("%d ",sum[aa][bb]+sum[a-1][b-1]-sum[a-1][bb]-sum[aa][b-1]);
}
printf("\n");
}
printf("\n");
}
return 0;
}
1452



被折叠的 条评论
为什么被折叠?



