DFS的简单应用,比较繁琐的是处理输入的英文字母。用并查集也可以做(可是笔者现在还没有掌握并查集,之前只用过一次,以后学会回来补上)
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 int m,n,typ[12][4]={{1,1,0,0},{1,0,1,0},{0,1,0,1},{0,0,1,1},{1,0,0,1},{0,1,1,0},{1,1,1,0},{1,1,0,1},{0,1,1,1},{1,0,1,1},{1,1,1,1},{0,0,0,0}}; 5 int dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}},a[55][55],cnt;//这里处理的方法是将不同种类的管子标号为0——3,可能联通就是1,不然就是0 6 char tem[50]; 7 void dfs(int si,int sj) 8 { 9 int x1,y1,kind=a[si][sj],z; 10 a[si][sj]=11;//第一步就是先将这个格子初始化为第11种,即各个方向都不联通的格子 11 for(int i=0;i<4;i++) 12 { 13 z=typ[kind][i]; 14 if(z==1) 15 { 16 x1=si+dir[i][0]; 17 y1=sj+dir[i][1]; 18 if(x1<0||x1>=m||y1<0||y1>=n||typ[a[x1][y1]][3-i]==0)//如果超出范围或无法联通则continue; 19 continue; 20 else 21 { 22 dfs(x1,y1); 23 } 24 } 25 } 26 return; 27 } 28 int main(){ 29 while(scanf("%d%d",&m,&n)) 30 { 31 int i,j; 32 cnt=0; 33 if(m<0||n<0) 34 break; 35 else 36 { 37 for(i=0;i<m;i++) 38 { 39 scanf("%s",tem); 40 for(j=0;j<n;j++) 41 { 42 a[i][j]=tem[j]-'A';//对每个英文字母处理,之前已经为此建好了数组 43 } 44 } 45 for(i=0;i<m;i++) 46 { 47 for(j=0;j<n;j++) 48 if(a[i][j]!=11) 49 { 50 cnt++;//每个新看见的非11的格子均为可能联通一大块的整体。 51 dfs(i,j); 52 } 53 } 54 } 55 printf("%d ",cnt); 56 } 57 }