这道题可能刚拿到手的话比较困难,不知如何下手。
但是分析一下貌似用搜索和并查集可以搞定。
下面提供并查集的代码,具体详解在代码注释
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3463 Accepted Submission(s): 1533
2 2 DK HF 3 3 ADC FJK IHE -1 -1
2 3
#include <iostream> #include <stdlib.h> #include <algorithm> #include <math.h> using namespace std; const int M = 60; struct node{ //保存格子水管有哪个方向的路线 int s; //上 int x; //下 int z; //左 int y; //右 }; node T[M][M]; int father[ 4000 ]; //虽然是二维的,但是为了方便,用一维数组来存祖先节点 //( i*60 + j )i为行,j为列,得数即为这个格子的祖先的数值 int n,m; char s; void initial( ) { for( int i=0 ; i<M ; i++ ) for( int j=0 ; j<M ; j++ ){ father[i*60+j] = i*60+j; //因为输入的行列数不超过50,所以乘以了60 T[i][j].s = T[i][j].x = T[i][j].z = T[i][j].y = 0; } } void solve( int i , int j , char c ) //来处理每个格子的状态 { if( c == 'A' ){ T[i][j].s = 1;T[i][j].x = 0; T[i][j].z = 1;T[i][j].y = 0; } else if( c == 'B' ){ T[i][j].s = 1;T[i][j].x = 0; T[i][j].z = 0;T[i][j].y = 1; } else if( c == 'C' ){ T[i][j].s = 0;T[i][j].x = 1; T[i][j].z = 1;T[i][j].y = 0; } else if( c == 'D' ){ T[i][j].s = 0;T[i][j].x = 1; T[i][j].z = 0;T[i][j].y = 1; } else if( c == 'E' ){ T[i][j].s = 1;T[i][j].x = 1; T[i][j].z = 0;T[i][j].y = 0; } else if( c == 'F' ){ T[i][j].s = 0;T[i][j].x = 0; T[i][j].z = 1;T[i][j].y = 1; } else if( c == 'G' ){ T[i][j].s = 1;T[i][j].x = 0; T[i][j].z = 1;T[i][j].y = 1; } else if( c == 'H' ){ T[i][j].s = 1;T[i][j].x = 1; T[i][j].z = 1;T[i][j].y = 0; }else if( c == 'I' ){ T[i][j].s = 0;T[i][j].x = 1; T[i][j].z = 1;T[i][j].y = 1; } else if( c == 'J' ){ T[i][j].s = 1;T[i][j].x = 1; T[i][j].z = 0;T[i][j].y = 1; } else if( c == 'K' ){ T[i][j].s = 1;T[i][j].x = 1; T[i][j].z = 1;T[i][j].y = 1; } } int find( int x ) { return x == father[x] ? x : father[x] = find( father[x] ); } void merge( int a , int b ) { int x ,y; x = find( a ); y = find( b ); if( x != y ){ father[y] = x; } } bool fun( int i , int j ) //查看是否和4个相邻位置的格子有连通,有的话就合并 { bool flag = false; if( T[i][j].s && T[i-1][j].x ) {merge( (i*60)+j , (i-1)*60+j );flag=true;} if( T[i][j].x && T[i+1][j].s ) {merge( (i*60)+j , (i+1)*60+j );flag=true;} if( T[i][j].z && T[i][j-1].y ) {merge( (i*60)+j , (i*60)+j-1 );flag=true;} if( T[i][j].y && T[i][j+1].z ) {merge( (i*60)+j , (i*60)+j+1 );flag=true;} if( flag ) return false; else return true; } int main() { while( scanf("%d%d",&n,&m) == 2 ){ if( n==-1 && m==-1 ) break; initial( ); getchar( ); for( int i=1 ; i<=n ; i++ ){ for( int j=1 ; j<=m ; ++j ){ scanf("%c",&s); solve( i , j , s ); } getchar( ); } int ans = 0; for( int i=1 ; i<=n ; i++ ){ for( int j=1 ; j<=m ; j++ ){ fun( i , j ); } } for( int i=1 ; i<=n ; i++ ){ for( int j=1 ; j<=m ; j++ ){ //printf("%d ",father[i*60+j]); if( father[i*60+j] == i*60+j ) ans++; } //printf("\n"); } printf("%d\n",ans); } return 0; }