AcWing 181. 回转游戏
IDA*搜索,预估值就是f(),计算中间八个块最多的数字离8还差几,这次搜索没有明确限制搜索的层数
#includeusing namespace std; const int N = 24; int q[N]; int oppsite[8] = {5, 4, 7, 6, 1, 0, 3, 2}; //与下标序号对应的相反的操作 int center[8] = {6, 7, 8, 11, 12, 15, 16, 17}; //中间八个块的下标 int path[N]; int op[8][7] = { {0, 2, 6, 11, 15, 20, 22}, {1, 3, 8, 12, 17, 21, 23}, {10, 9, 8, 7, 6, 5, 4}, {19, 18, 17, 16, 15, 14, 13}, {23, 21, 17, 12, 8, 3, 1}, {22, 20, 15, 11, 6, 2, 0}, {13, 14, 15, 16, 17, 18, 19}, {4, 5, 6, 7, 8, 9, 10} }; int f(){ //预估函数,求出中中间一圈最少还需要几步才能全部一致 int state[4] = {0}; for(int i = 0; i < 8; i ++ ){ state[q[center[i]]] ++ ; } int maxv= 0; for(int i = 1; i <= 3; i ++ ){ maxv = max(maxv, state[i]); } return 8 - maxv; } void operate(int x){ int t = q[op[x][0]]; for(int i = 0; i < 6; i ++ ){ q[op[x][i]] = q[op[x][i + 1]]; } q[op[x][6]] = t; } bool dfs(int depth, int max_depth, int last){ if(f() + depth > max_depth) return false; if(!f()) return true; for(int i = 0; i < 8; i ++ ){ if(last != oppsite[i]){//剪枝之一 ,避免刚进行完的操作又进行他的逆操作 operate(i); path[depth] = i; if(dfs(depth + 1, max_depth, i)) return true; operate(oppsite[i]); } } return false; } int main() { while(cin>>q[0], q[0]){ for(int i = 1; i < 24; i ++ ) cin>>q[i]; int depth = 0; while(!dfs(0, depth, -1)) depth ++ ; if(!depth) printf("No moves needed"); else{ for(int i = 0; i < depth; i ++ ){ printf("%c", 'A' + path[i]); } } cout<



