相对1150题来说,这道题的N可能超过10,所以需要进行排重,即相同状态的魔板不要重复压倒队列里,这里我用map储存操作过的状态,也可以用康托编码来储存状态,这样时间缩短为0.03秒。关于康托展开可以参考,其可用数学归纳法证明:http://www.cnblogs.com/1-2-3/archive/2011/04/25/generate-permutation-part2.html
1 #include <bits/stdc++.h> 2 using namespace std; 3 map<int, int>visit; 4 int op_a(int n) {//操作A(上下行互换) 5 int low = n % 10000; 6 int high = n / 10000; 7 return low * 10000 + high; 8 } 9 10 int op_b(int n) {//操作B(每次以行循环右移一个) 11 int low = n % 10000; 12 int high = n / 10000; 13 int h = high % 10; 14 high = h * 1000 + high / 10; 15 int l = low % 10; 16 low = l * 1000 + low / 10; 17 return high * 10000 + low; 18 } 19 20 int op_c(int n) {//操作C(中间四小块顺时针转一格) 21 int a[8]; 22 for (int i = 0; i < 8; i++) { 23 a[7-i] = n % 10; 24 n = n / 10; 25 } 26 int ans = a[0] * 10000000 + 27 a[5] * 1000000 + 28 a[1] * 100000 + 29 a[3] * 10000 + 30 a[4] * 1000 + 31 a[6] * 100 + 32 a[2] * 10 + 33 a[7]; 34 return ans; 35 } 36 struct Node { 37 int num;//num储存状态,用8位的十进制数来储存状态 38 vector<char> path;//path储存操作 39 }; 40 Node bfs(int step, int n) { 41 queue<Node> q; 42 Node front; 43 front.num = 12348765;//初始的魔板 44 visit[front.num] = 1; 45 q.push(front); 46 if(front.num == n)return front; 47 48 while (!q.empty()) { 49 front = q.front(); 50 q.pop(); 51 if (front.path.size() > step) { 52 return front;//如果操作的次数大于step数,返回 53 } 54 //依次进行三种操作 55 Node tmp1 = front; 56 57 tmp1.num = op_a(front.num); 58 tmp1.path.push_back('A'); 59 if (tmp1.num == n) { 60 return tmp1; 61 } 62 else if(visit.find(tmp1.num) == visit.end()){ 63 visit[tmp1.num] = 1; 64 q.push(tmp1); 65 } 66 67 Node tmp2 = front; 68 tmp2.num = op_b(front.num); 69 tmp2.path.push_back('B'); 70 if (tmp2.num == n) { 71 return tmp2; 72 } 73 else if(visit.find(tmp2.num) == visit.end()){ 74 visit[tmp2.num] = 1; 75 q.push(tmp2); 76 } 77 78 Node tmp3 = front; 79 tmp3.num = op_c(front.num); 80 tmp3.path.push_back('C'); 81 if (tmp3.num == n) { 82 return tmp3; 83 } 84 else if(visit.find(tmp3.num) == visit.end()){ 85 visit[tmp3.num] = 1; 86 q.push(tmp3); 87 } 88 89 } 90 } 91 int main(){ 92 int step; 93 while (cin >> step && step != -1) { 94 int ans = 0; 95 int a; 96 for (int i = 0; i < 8; i++) {//将魔板转换成数字 97 cin >> a; 98 ans = 10 * ans + a; 99 } 100 101 visit.clear(); 102 Node node = bfs(step, ans); 103 if (node.path.size() > step) cout << "-1" << endl;//如失败则输出-1,否则输出path 104 else { 105 cout << node.path.size() << " "; 106 for (int i = 0; i < node.path.size(); i++) { 107 cout << node.path[i]; 108 } 109 cout << endl; 110 } 111 112 } 113 return 0; 114 }