Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5809 Accepted Submission(s): 2516
这道题就是问给定的图中能构成几个连通块。
既然是求连通块,那么就可以用并查集来做,但是这里怎么去判断连通情况要考虑考虑
我假定每一个方块有四个方向,如果这个方向能延伸出去和其他方块连通的话,那么就给这个方向设定为1,否则为0
然后对每一个方块进行枚举,如果能连通就合并。
最后统计根节点个数就行了。
1 #include<cstdio> 2 #include<cstring> 3 #include<stdlib.h> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN=55; 7 char ch; 8 int a[MAXN][MAXN],p[MAXN*MAXN]; 9 int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//寻找方向:上右下左 10 int map[11][4]={{1,0,0,1},//从上右下左四个方向依次列出每一个方块的连通情况 11 {1,1,0,0}, 12 {0,0,1,1}, 13 {0,1,1,0}, 14 {1,0,1,0}, 15 {0,1,0,1}, 16 {1,1,0,1}, 17 {1,0,1,1}, 18 {0,1,1,1}, 19 {1,1,1,0}, 20 {1,1,1,1} 21 }; 22 int Find(int x) 23 { 24 return p[x]==x?x:p[x]=Find(p[x]); 25 } 26 27 void Union(int a,int b) 28 { 29 int x=Find(a); 30 int y=Find(b); 31 if(x!=y) 32 p[x]=y; 33 } 34 35 int main() 36 { 37 //freopen("in.txt","r",stdin); 38 int n,m; 39 while(scanf("%d %d%*c",&m,&n)&&m>0) 40 { 41 for(int i=0;i<m;i++) 42 { 43 for(int j=0;j<n;j++) 44 { 45 scanf("%c",&ch); 46 a[i][j]=ch-'A'; 47 } 48 getchar(); 49 } 50 51 for(int i=0;i<n*m;i++) 52 p[i]=i; 53 54 for(int i=0;i<m;i++) 55 { 56 for(int j=0;j<n;j++) 57 { 58 for(int k=0;k<4;k++) 59 { 60 int next_x,next_y; 61 next_x=i+dir[k][0]; 62 next_y=j+dir[k][1]; 63 if(0<=next_x&&next_x<m&&0<=next_y&&next_y<n) 64 { 65 if(k==0) 66 { 67 if(map[a[next_x][next_y]][2]&&map[a[i][j]][0]) 68 Union(next_x*n+next_y,i*n+j); 69 } 70 if(k==1) 71 { 72 if(map[a[next_x][next_y]][3]&&map[a[i][j]][1]) 73 Union(next_x*n+next_y,i*n+j); 74 } 75 if(k==2) 76 { 77 if(map[a[next_x][next_y]][0]&&map[a[i][j]][2]) 78 Union(next_x*n+next_y,i*n+j); 79 } 80 if(k==3) 81 { 82 if(map[a[next_x][next_y]][1]&&map[a[i][j]][3]) 83 Union(next_x*n+next_y,i*n+j); 84 } 85 } 86 } 87 } 88 } 89 // for(int i=0;i<n*m;i++) 90 // printf("%d ",p[i]); 91 // printf("\n"); 92 93 int cnt=0; 94 for(int i=0;i<n*m;i++) 95 if(p[i]==i) 96 cnt++; 97 printf("%d\n",cnt); 98 } 99 }