标签:
2 2 DK HF 3 3 ADC FJK IHE -1 -1
2 3
题解:使用并查集,遍历每个格子的方向,把可以连通的相邻的两个格子合并成一个集合。输出N*M-Count就是独立集合的个数、
注意,并查集的数组需要开大点,开小了结果Tle了好几次。。。
代码:2015/10/20
1 #include <iostream> 2 #include <stdio.h> 3 #define Max 5200 4 using namespace std; 5 int DicX[4]={0,-1,0,1}; 6 int DicY[4]={-1,0,1,0}; 7 int Sign[15][4]={ 8 1,1,0,0,//A 9 0,1,1,0,//B 10 1,0,0,1,//C 11 0,0,1,1,//D 12 0,1,0,1,//E 13 1,0,1,0,//F 14 1,1,1,0,//G 15 1,1,0,1,//H 16 1,0,1,1,//I 17 0,1,1,1,//J 18 1,1,1,1//K 19 }; 20 int ID[Max]; 21 char Str[Max][Max]; 22 void Cread(int N) 23 { 24 for(int i=0;i<=N;i++)ID[i]=i; 25 } 26 int Find(int x) 27 { 28 if(x!=ID[x])ID[x]=Find(ID[x]); 29 return ID[x]; 30 } 31 int main() 32 { 33 int N,M,i,j,k,d; 34 while(scanf("%d%d",&N,&M)!=EOF) 35 { 36 if(N<0||M<0)break; 37 for(i=0;i<N;i++){ 38 scanf("%s",Str[i]); 39 } 40 int Count=0; 41 Cread(N*M); 42 for(i=0;i<N;i++)//遍历每一个格子 43 { 44 for(j=0;j<M;j++) 45 { 46 for(k=0;k<4;k++)//遍历当前格子的四个方向 47 { 48 int ii=i+DicX[k]; 49 int jj=j+DicY[k]; 50 51 if(ii<0||jj<0||ii>=N||jj>=M)continue; 52 if(Sign[Str[i][j]-‘A‘][k]&&Sign[Str[ii][jj]-‘A‘][(k+2)%4]) 53 {//判断当前格子的四个方向与所相邻格子的是否可连通 54 int A=Find(i*M+j); 55 int B=Find(ii*M+jj); 56 if(A!=B)//合并可连通的集合 57 { 58 ID[A]=B; 59 Count++; 60 } 61 } 62 } 63 } 64 } 65 printf("%d\n",N*M-Count);//输出集合的个数 66 } 67 return 0; 68 }
标签:
原文地址:http://www.cnblogs.com/LWF5201314614/p/4896058.html