题意:有24个只由「1,2,3」组成的格子,我们希望中间的8个格子的值是相同的,现在有8种移动的方式,A~H,分别将这些格子向这个方向上走,且第一个变成最后一个。然后,询问最少的次数(同最少时候,字典序最小),满足中间的8个格子是相同的,并输出这样的移动方式,以及最后的中间8个格子的答案是什么?
思路:我们先设置一个阀值maxH,然后利用启发式的寻找是否可以在该阀值内找到答案,如果说当前已经走过的步数d+估值函数h是大于等于阀值maxH的,那么说明这个方式不优,这里就需要剪枝了,利用这样的剪枝方式,我们来判断当前阀值maxH是否是答案,或者是偏小了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <string> 5 #include <cstring> 6 #include <algorithm> 7 #include <limits> 8 #include <vector> 9 #include <stack> 10 #include <queue> 11 #include <set> 12 #include <map> 13 #include <bitset> 14 #define lowbit(x) ( x&(-x) ) 15 #define pi 3.141592653589793 16 #define e 2.718281828459045 17 #define INF 0x3f3f3f3f 18 #define HalF (l + r)>>1 19 #define lsn rt<<1 20 #define rsn rt<<1|1 21 #define Lson lsn, l, mid 22 #define Rson rsn, mid+1, r 23 #define QL Lson, ql, qr 24 #define QR Rson, ql, qr 25 #define myself rt, l, r 26 #define pii pair<int, int> 27 #define MP(a, b) make_pair(a, b) 28 using namespace std; 29 typedef unsigned long long ull; 30 typedef unsigned int uit; 31 typedef long long ll; 32 const char op[] = "ABCDEFGH"; 33 const int dir[8][7] = 34 { 35 0, 2, 6, 11, 15, 20, 22, 36 1, 3, 8, 12, 17, 21, 23, 37 10, 9, 8, 7, 6, 5, 4, 38 19, 18, 17, 16, 15, 14, 13, 39 23, 21, 17, 12, 8, 3, 1, 40 22, 20, 15, 11, 6, 2, 0, 41 13, 14, 15, 16, 17, 18, 19, 42 4, 5, 6, 7, 8, 9, 10 43 }; 44 const int mid[] = {6, 7, 8, 11, 12, 15, 16, 17}; 45 const int re[] = {5, 4, 7, 6, 1, 0, 3, 2}; 46 const int maxN = 240; 47 int Path[maxN], a[24]; 48 inline int get_H(int s[]) 49 { 50 int cnt[] = {0, 0, 0}; 51 for(int i = 0; i < 8; i ++) cnt[s[mid[i]] - 1] ++; 52 return 8 - max(cnt[0], max(cnt[1], cnt[2])); 53 } 54 void Move(int op) 55 { 56 int las = a[dir[op][0]]; 57 for(int i = 1; i < 7; i++) a[dir[op][i - 1]] = a[dir[op][i]]; 58 a[dir[op][6]] = las; 59 } 60 int depth; 61 bool IDA_star(int d) 62 { 63 if(d >= depth) return false; 64 for(int i = 0; i < 8; i++) 65 { 66 Move(i); 67 Path[d] = i; 68 int h = get_H(a); 69 if(!h) return true; 70 if(d + h < depth && IDA_star(d + 1)) return true; 71 Move(re[i]); 72 } 73 return false; 74 } 75 int main() 76 { 77 while(scanf("%d", &a[0]) && a[0]) 78 { 79 for(int i = 1; i < 24; i ++) scanf("%d", &a[i]); 80 depth = get_H(a); 81 if(!depth) 82 { 83 printf("No moves needed\n"); 84 printf("%d\n", a[mid[0]]); 85 } 86 else 87 { 88 while(!IDA_star(0)) depth++; 89 for(int i = 0; i < depth; i ++) printf("%c", op[Path[i]]); 90 printf("\n"); 91 printf("%d\n", a[mid[0]]); 92 } 93 } 94 return 0; 95 }