本废物的第一篇博客,正好在写这道题,就拿来练练手了。也就写写这种基础题目了
传送门:https://www.luogu.org/problemnew/show/P1141
裸上bfs会TLE,我们可以发现同一个连通图上的点的答案应该是一样的。所以选择用连通图来优化一下,速度超级加倍。
代码如下:
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 int map[1005][1005]; 6 int flag[1005][1005],ans[1000005];//ans一定要开大一点 因为坐标可以有1e6种。 7 int toward[4][2]={0,1,0,-1,1,0,-1,0}; 8 int n,m; 9 struct node{ 10 int x,y; 11 }p,head; 12 int bfs(int x,int y,int cnt){//我用了队列来写bfs,实际上数组也是ok的,有空更新数组写法,本质上是一样的。 13 int ans=1; 14 queue<node> q; 15 p.x=x; 16 p.y=y; 17 q.push(p); 18 while(!q.empty()){ 19 head=q.front(); 20 q.pop(); 21 for(int i=0;i<4;i++){ 22 p.x=head.x+toward[i][0]; 23 p.y=head.y+toward[i][1]; 24 if(p.x<1||p.x>n||p.y<1||p.y>n||flag[p.x][p.y]!=0) 25 continue; 26 else{ 27 if(map[p.x][p.y]!=map[head.x][head.y]){ 28 //book[p.x][p.y]=1; 29 q.push(p); 30 flag[p.x][p.y]=cnt; 31 ans++; 32 } 33 } 34 } 35 } 36 return ans; 37 } 38 int main(){ 39 char t[1005]; 40 scanf("%d %d",&n,&m); 41 for(int i=1;i<=n;i++){ 42 scanf("%s",t); 43 for(int j=1;j<=n;j++){ 44 map[i][j]=t[j-1]-'0';//把坐标从字符串换成数字,不做这步也可以,下面的代码需要稍微改动。 45 } 46 } 47 memset(flag,0,sizeof(flag)); 48 int cnt=0; 49 for(int i=1;i<=n;i++){ 50 for(int j=1;j<=n;j++){ 51 if(flag[i][j]==0){ 52 flag[i][j]=++cnt; 53 ans[cnt]=bfs(i,j,cnt); 54 } 55 } 56 } 57 int x,y; 58 for(int i=0;i<m;i++){ 59 scanf("%d %d",&x,&y); 60 printf("%d\n",ans[flag[x][y]]); 61 } 62 return 0; 63 }