B30 IDA*算法 The Rotation Game
视频链接:131 IDA*算法 The Rotation Game_哔哩哔哩_bilibili
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int op[8][7]={ //8个操作的格子编号 {0,2,6,11,15,20,22}, //A {1,3,8,12,17,21,23}, //B {10,9,8,7,6,5,4}, //C {19,18,17,16,15,14,13},//D {23,21,17,12,8,3,1}, //E {22,20,15,11,6,2,0}, //F {13,14,15,16,17,18,19},//G {4,5,6,7,8,9,10} //H }; int cent[8]={6,7,8,11,12,15,16,17}; //中心 int iop[8]={5,4,7,6,1,0,3,2}; //逆操作 int dep,a[24],path[100]; void operate(int x){ //第x种操作 int t=a[op[x][0]]; for(int i=0; i<6; i++) a[op[x][i]]=a[op[x][i+1]]; a[op[x][6]]=t; } bool check(){ //中心数字是否相同 for(int i=1; i<8; i++) if(a[cent[i]]!=a[cent[0]]) return false; return true; } int f(){ //估价函数: f=8-k static int cnt[4]; memset(cnt,0,sizeof cnt); for(int i=0; i<8; i++) cnt[a[cent[i]]]++; int k=0; //中心数字最多的出现次数为k for(int i=1; i<=3; i++) k=max(k,cnt[i]); return 8-k; //换掉不同数字,至少操作8-k次 } //第u层, 上一次操作为last bool dfs(int u,int last){ if(u+f()>dep) return false; if(check()) return true; for(int i=0; i<8; i++){ if(iop[i]==last) continue; operate(i); //操作一次 path[u]=i; if(dfs(u+1,i)) return true; operate(iop[i]); //恢复现场 } return false; } int main(){ while(scanf("%d",&a[0]),a[0]){ for(int i=1;i<24;i++)scanf("%d",&a[i]); for(dep=0; !dfs(0,-1); dep++); if(!dep) printf("No moves needed"); for(int i=0; i<dep; i++) printf("%c",'A'+path[i]); printf("\n%d\n",a[6]); } }