城市统计【BFS】
題目大意:
中山市的地圖是一個(gè)n*n的矩陣,其中標(biāo)號(hào)為1的表示商業(yè)區(qū),標(biāo)號(hào)為0的表示居民區(qū)。為了考察市內(nèi)居民區(qū)與商業(yè)區(qū)的距離,并對(duì)此作出評(píng)估,市長(zhǎng)希望你能夠編寫(xiě)一個(gè)程序完成這一任務(wù)。
居民區(qū)i到商業(yè)區(qū)的距離指的是到距離它最近的商業(yè)區(qū)j的距離(|Xi-Xj|+|Yi-Yj|),而你將統(tǒng)計(jì)的是對(duì)于城市中的每一個(gè)區(qū)域k,以它為中心,所有滿(mǎn)足max(|Xk-Xm|,|Yk-Ym|)<=r的區(qū)域m到商業(yè)區(qū)距離之和。結(jié)果同樣以n*n的矩陣形式輸出。
思路:
70分:?
O(n4)直接暴力求解即可。
100分:
BFS
首先在讀入的時(shí)候,若這個(gè)點(diǎn)是商業(yè)區(qū),就先將它入隊(duì),之后跑一邊BFS,求出每個(gè)居民區(qū)到商業(yè)區(qū)的距離(由于每個(gè)點(diǎn)只要訪問(wèn)1次,所以時(shí)間復(fù)雜度為O(n2)),之后用二維前綴和加速,輸出每個(gè)位置的答案。總時(shí)間復(fù)雜度為O(tn2)。
代碼:
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 using namespace std; 5 6 const int dx[]={0,0,0,1,-1}; 7 const int dy[]={0,1,-1,0,0}; 8 int a[301][301],b[301][301],p[301][301],t,n,r,sum,head,tail,state[500001][3]; 9 10 int abs(int x) 11 { 12 if (x>0) return x; 13 return -x; 14 } 15 16 int minn(int x) 17 { 18 return min(x,n); 19 } 20 21 int maxn(int x) 22 { 23 return max(x,0); 24 } 25 26 void bfs() 27 { 28 do 29 { 30 head++; 31 for (int i=1;i<=4;i++) //向四個(gè)方向擴(kuò)展 32 { 33 int xx=state[head][1]+dx[i]; 34 int yy=state[head][2]+dy[i]; 35 if (xx<0||xx>n||yy<0||yy>n||p[xx][yy]) continue; 36 tail++; //入隊(duì) 37 p[xx][yy]=1; 38 state[tail][1]=xx; 39 state[tail][2]=yy; 40 b[xx][yy]=b[state[head][1]][state[head][2]]+1; 41 } 42 } 43 while (head<tail); 44 return; 45 } 46 47 int main() 48 { 49 scanf("%d",&t); 50 while (t--) 51 { 52 memset(b,0,sizeof(b)); 53 memset(a,0,sizeof(a)); 54 memset(p,0,sizeof(p)); 55 scanf("%d%d",&n,&r); 56 for (int i=1;i<=n;i++) 57 for (int j=1;j<=n;j++) 58 { 59 scanf("%d",&a[i][j]); 60 a[i][j]++; 61 if (a[i][j]==2) //商業(yè)區(qū) 62 { 63 tail++; //入隊(duì) 64 state[tail][1]=i; 65 state[tail][2]=j; 66 p[i][j]=1; 67 } 68 } 69 bfs(); 70 for (int i=1;i<=n;i++) 71 for (int j=1;j<=n;j++) 72 b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1]; //前綴和 73 for (int i=1;i<=n;i++) 74 { 75 for (int j=1;j<=n;j++) 76 printf("%d ",b[minn(i+r)][minn(j+r)]-b[maxn(i-r-1)][minn(j+r)]-b[minn(i+r)][maxn(j-r-1)]+b[maxn(i-r-1)][maxn(j-r-1)]); 77 putchar(10); 78 } 79 putchar(10); 80 } 81 return 0; 82 }?
轉(zhuǎn)載于:https://www.cnblogs.com/hello-tomorrow/p/9314772.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
- 上一篇: 8月18日 小雨
- 下一篇: win10看视频背景声音大、人声小、或其