题目来源: http://acm.zju.edu.cn/onlinejudge/showRuns.do?contestId=1
求连通分量的个数:
搜索时从第一个字符(对应一个正方形)开始,每搜索到一个正方形,对该位置的四个可能方向进行下一步搜索,下一步搜索需要满足的条件是 当前这个正方形有某个方向的搜索方向且下一个正方形也有这个方向的接受(连接)方向,故可进行一步搜索。例如 当前的可走的某个方向为“上”,则下一个正方形的连接方向应该为“下”,同理。上 --下,右-- 左, 下--上, 左---右。 往前走一步,要将当前正方形设置为已访问,表示当前搜索过程不能回到经过的正方形。 一旦前进不了,要回退,回到上一步的情形。
代码如下:
1 #include<iostream> 2 #include<stdio.h> 3 #include<string> 4 #include<string.h> 5 #define N 55 6 using namespace std; 7 char map[N][N]; 8 int flag[N][N]; 9 int m,n; 10 int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}} ; // 方向是上右下左的顺时针 11 // tube1 可走的方向 12 // tube2 可被选的方向, 13 //搜索需满足这个正方形可以走的方向,且下一个正方形在该方向可被走(连接),故可搜索下一个正方形 14 15 int tube1[11][4]={{1,0,0,1},{1,1,0,0},{0,0,1,1},{0,1,1,0},{1,0,1,0},{0,1,0,1},{1,1,0,1},{1,0,1,1},{0,1,1,1},{1,1,1,0},{1,1,1,1}}; 16 int tube2[11][4]={{0,1,1,0},{0,0,1,1},{1,1,0,0},{1,0,0,1},{1,0,1,0},{0,1,0,1},{0,1,1,1},{1,1,1,0},{1,1,0,1},{1,0,1,1},{1,1,1,1}}; 17 void dfs(int x,int y) 18 { 19 int i,xx,yy; 20 if(flag[x][y] ) return ; //???????要return 21 flag[x][y]= 1; 22 for(i=0;i<4;i++) 23 { 24 if(tube1[map[x][y]-'A'][i]) 25 { 26 xx=x+dir[i][0]; 27 yy=y+dir[i][1]; 28 if(xx<0 || xx>m || yy<0 || yy>n) continue; 29 if(tube2[map[xx][yy]-'A'][i]) 30 dfs(xx,yy); 31 } 32 } 33 } 34 int main() 35 { 36 while(cin>>m>>n &&m>=0 &&n>=0) 37 { 38 int i,j,count; 39 count= 0; 40 for(i=0;i<m;i++) 41 { 42 for(j=0;j<n;j++) 43 { 44 cin>>map[i][j]; 45 flag[i][j]=0; 46 } 47 } 48 for(i=0;i<m;i++) 49 { 50 for(j=0;j<n;j++) 51 { 52 if(flag[i][j] == 0) 53 { 54 dfs(i,j); 55 count++; 56 } 57 } 58 } 59 cout<<count<<endl; 60 61 } 62 return 0 ; 63 }