POJ-2965 The Pilots Brothers' refrigerator 枚举 状态压缩
做法与1753相似。
代码如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #define START 0 #define END 65535 using namespace std; char G[6][6]; int status, cpy, how[20], path[20], times; void pre() { how[1] = 4383, how[2] =8751, how[3] = 17487, how[4] = 34959, how[5] = 4593; how[6] = 8946, how[7] = 17652, how[8] = 35064, how[9] = 7953, how[10] = 12066; how[11] = 20292, how[12] = 36744, how[13] = 61713, how[14] = 61986; how[15] = 62532, how[16] = 63624; // 对每一个点进行反转所影响的区域的位压缩存储 } bool dfs(int cur, int pos, int leavings) { if (leavings == 0) { // 当组合排列完毕 cpy = status; for (int i = 0; i < pos; ++i) { cpy ^= how[path[i]]; } if (cpy == START) { printf("%d\n", times); for (int i = 0; i < pos; ++i) { printf("%d %d\n", (path[i]-1)/4+1, (path[i]-1)%4+1); } return true; } else { return false; } } else { for (int i = cur; i <= 16; ++i) { path[pos] = i; if (16-pos < leavings) { continue; } if (dfs(i+1, pos+1, leavings-1)) { return true; } } return false; } } bool OK(int times) { if (dfs(1, 0, times)) { return true; } else { return false; } } int main() { pre(); // 读入数据 for (int i = 1; i <= 4; ++i) { scanf("%s", G[i]+1); for (int j = 1; j <= 4; ++j) { G[i][j] = G[i][j] == '-' ? 0 : 1; } } for (int i = 4; i >= 1; --i) { for (int j = 4; j >= 1; --j) { status <<= 1; if (G[i][j]) { status |= 1; // 将整个图压缩到一个32位的数字中 } } } bool finish = false; while (!finish) { if (OK(times)) { finish = true; } else { ++times; } } return 0; }