http://poj.org/problem?id=2965
题意:
一个4*4的矩形,有'+'和'-'两种符号,每次可以转换一个坐标的符号,同时该列和该行上的其他符号也要随之改变。最少需要几次才能全部变成'-'。
思路:
这道题和黑白棋那道题目差不多,唯一的差别就是需要记录一下路径。
我是用BFS来做的,用二进制来存储。翻转时用位运算的异或比较方便,可以看一下我的这篇博客(http://www.cnblogs.com/zyb993963526/p/6347741.html),上面写的比较清楚。
1 #include <iostream> 2 #include <algorithm> 3 #include<queue> 4 using namespace std; 5 6 const int maxn = 65536; 7 8 int map[5][5]; 9 char s; 10 int vis[maxn]; 11 int sum; 12 13 int fac[] = { 63624, 62532, 61986, 61713, 14 36744, 20292, 12066, 7953, 15 35064, 17652, 8946, 4593, 16 34959, 17487, 8751, 4383 }; 17 18 struct node 19 { 20 int x; 21 int d; 22 }; 23 24 struct node2 25 { 26 int pa; 27 int i; 28 }path[maxn]; 29 30 31 void print_ans(int k) 32 { 33 if (path[k].pa == sum) 34 { 35 cout << path[k].i / 4 + 1 << " " << path[k].i % 4 + 1 << endl; 36 return; 37 } 38 print_ans(path[k].pa); 39 cout << path[k].i / 4+1 << " " << path[k].i % 4+1 << endl; 40 } 41 42 void bfs() 43 { 44 queue<node> q; 45 node p; 46 p.x = sum; 47 p.d = 0; 48 q.push(p); 49 vis[p.x] = 1; 50 while (!q.empty()) 51 { 52 node u = q.front(); 53 q.pop(); 54 if (u.x == 65535) 55 { 56 cout << u.d << endl; 57 print_ans(u.x); 58 return; 59 } 60 for (int i = 0; i < 16; i++) 61 { 62 int k = u.x^fac[i]; 63 if (!vis[k]) 64 { 65 vis[k] = 1; 66 node v; 67 v.x = k; 68 v.d = u.d + 1; 69 q.push(v); 70 path[k].pa = u.x; 71 path[k].i = i; 72 } 73 } 74 } 75 } 76 77 int main() 78 { 79 //freopen("D:\txt.txt", "r", stdin); 80 int cnt = 15; 81 for (int i = 0; i < 4; i++) 82 for (int j = 0; j < 4; j++) 83 { 84 cin >> s; 85 if (s == '-') 86 { 87 map[i][j] = 1; 88 sum += (1 << cnt); //二进制转换成十进制 89 } 90 else map[i][j] = 0; 91 cnt--; 92 } 93 bfs(); 94 return 0; 95 }