状态压缩+逆向BFS。
方向数组就是任意相邻的两点(初始化时减1),每个顶点均有4个相邻点。因此,共有16*4/2=32个方向。按序排列即可找到。
1 /* 3220 */ 2 #include <iostream> 3 #include <queue> 4 #include <algorithm> 5 #include <cstdio> 6 #include <cstring> 7 using namespace std; 8 9 10 char visit[1<<17]; 11 const int end = 0x0ff; 12 int beg; 13 int dir[32][2] = { 14 1,2, 1,3, 1,5, 1,9, 15 2,4, 2,6, 2,10, 16 3,4, 3,7, 3,11, 17 4,8, 4,12, 18 5,6, 5,7, 5,13, 19 6,8, 6,14, 20 7,8, 7,15, 21 8,16, 22 9,10, 9,11, 9,13, 23 10,12, 10,14, 24 11,12, 11,15, 25 12,16, 26 13,14, 13,15, 27 14,16, 28 15,16 29 }; 30 31 void bfs() { 32 int i, j, k, tmp; 33 queue<int> Q; 34 int a, b, s; 35 char t; 36 37 memset(visit, -1, sizeof(visit)); 38 visit[end] = 0; 39 Q.push(end); 40 41 while (!Q.empty()) { 42 s = Q.front(); 43 Q.pop(); 44 t = visit[s]; 45 if (t >= 3) 46 continue; 47 ++t; 48 for (i=0; i<32; ++i) { 49 a = s & (1<<dir[i][0]); 50 b = s & (1<<dir[i][1]); 51 if (a ^ b) { 52 tmp = (s ^ (1<<dir[i][0])) ^ (1<<dir[i][1]); 53 if (visit[tmp] < 0) { 54 visit[tmp] = t; 55 Q.push(tmp); 56 } 57 } 58 } 59 } 60 } 61 62 void init() { 63 int i; 64 65 for (i=0; i<32; ++i) { 66 --dir[i][0]; 67 --dir[i][1]; 68 } 69 70 bfs(); 71 } 72 73 int main() { 74 int t, tt; 75 int i, j, k; 76 77 #ifndef ONLINE_JUDGE 78 freopen("data.in", "r", stdin); 79 freopen("data.out", "w", stdout); 80 #endif 81 82 init(); 83 scanf("%d", &tt); 84 for (t=1; t<=tt; ++t) { 85 beg = 0; 86 for (i=15; i>=0; --i) { 87 scanf("%d", &j); 88 if (j) 89 beg |= (1<<i); 90 } 91 k = visit[beg]; 92 if (k < 0) 93 printf("Case #%d: more\n", t); 94 else 95 printf("Case #%d: %d\n", t, k); 96 } 97 98 return 0; 99 }
时间: 2024-10-14 05:15:55