POJ 2965 The Pilots Brothers' refrigerator
题意: 4*4的矩阵, “+”表示关闭, “—”表示开启, 当改变一个位置的时候,其所在的行和列都会取反,求最少需要多少步能将其全部置为“-”。
思路:暴力枚举+BFS。 先写一个异或的数组,然后依次异或。 其中用pt 保存路径。
10957265 | NY_lv10 | 2965 | Accepted | 1240K | 938MS | C++ | 1103B | 2012-10-26 11:24:33 |
View Code
#include <iostream> #include <queue> using namespace std; int chang[] = { 63624, 62532, 61986, 61713, 36744, 20292, 12066, 7953, 35064, 17652, 8946, 4593, 34959, 17487,8751, 4383}; struct point { int x; //保存前驱 int y; //改变了哪个点 }; bool used[65536]; //数组65535 运行错误。。。⊙﹏⊙b汗 int step[65536]; int path[20]; point pt[65536]; int main() { queue<int> que; int id, n; char ch; int i, j; id = 0; for (i=0; i<16; i++) { id <<= 1; cin>>ch; if (ch == '+') id += 1; } memset(used, false, sizeof(used)); step[id] = 0; pt[id].x = id; n = id; used[id] = true; que.push(id); while (!que.empty()) { int tmp = que.front(); que.pop(); for (i=0; i<16; i++) { id = tmp; id ^= chang[i]; if (!used[id]) { used[id] = true; que.push(id); step[id] = step[tmp] + 1; pt[id].x = tmp; pt[id].y = i; } if (id == 0) goto L; } } L: cout<<step[0]<<endl; j = 0; while (id != n) { path[j++] = pt[id].y; id = pt[id].x; } for (i=j-1; i>=0; i--) cout<<path[i]/4+1<<" "<<path[i] % 4+1<<endl; return 0; }