简单BFS,就是题意理解了好长时间
题意:给你三个棋子,要求用最少的步数将这三个棋子移动到同一节点上。
每次可以沿一条边移动一个棋子,只有当该边的颜色与另外两个棋子之间的边的颜色相同时才可以移动。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <queue> 5 6 using namespace std; 7 8 const int MAXN = 60; 9 10 int n; 11 int st[3]; 12 bool vis[626262]; 13 int step[626262]; 14 char G[MAXN][MAXN]; 15 16 int GetHash( int a, int b, int c ) 17 { 18 return ( a * 100 + b ) * 100 + c; 19 } 20 21 int BFS() 22 { 23 memset( vis, false, sizeof(vis) ); 24 queue<int> Q; 25 26 int HashVal = GetHash( st[2], st[1], st[0] ); 27 Q.push( HashVal ); 28 vis[HashVal] = true; 29 step[HashVal] = 0; 30 31 while ( !Q.empty() ) 32 { 33 int cur[3], curval = Q.front(); 34 Q.pop(); 35 int temp = curval; 36 for ( int i = 0; i < 3; ++i ) 37 { 38 cur[i] = temp % 100; 39 temp /= 100; 40 } 41 42 if ( cur[0] == cur[1] && cur[1] == cur[2] ) return step[curval]; 43 44 for ( int i = 0; i < 3; ++i ) 45 for ( int j = 1; j <= n; ++j ) 46 { 47 if ( G[ cur[i] ][j] == G[ cur[ (i + 1)%3 ] ][ cur[ (i + 2)%3 ] ] ) 48 { 49 int tp = cur[i]; 50 cur[i] = j; 51 HashVal = GetHash( cur[2], cur[1], cur[0] ); 52 if ( !vis[HashVal] ) 53 { 54 vis[ HashVal ] = true; 55 step[ HashVal ] = step[ curval ] + 1; 56 if ( cur[i] == cur[ (i + 1)%3 ] && cur[i] == cur[ (i + 2)%3 ] ) return step[HashVal]; 57 Q.push( HashVal ); 58 } 59 60 cur[i] = tp; 61 } 62 } 63 64 } 65 return -1; 66 } 67 68 int main() 69 { 70 while ( scanf( "%d", &n ), n ) 71 { 72 for ( int i = 0; i < 3; ++i ) scanf( "%d", &st[i] ); 73 for ( int i = 1; i <= n; ++i ) 74 for ( int j = 1; j <= n; ++j ) 75 { 76 char temp[4]; 77 scanf( "%s", temp ); 78 G[i][j] = temp[0]; 79 } 80 81 int ans = BFS(); 82 if ( ans == -1 ) puts("impossible"); 83 else printf( "%d\n", ans ); 84 } 85 return 0; 86 }