因为8个转轮对应的位置比较没有规律,需要提前将这些位置存在数组中,方便旋转操作和回溯法的归位操作。
利用数组来人为储存没有规律的数字。
IDA*合了bfs步数最少和dfs字典序最小的优点。
#include<cstdio> #include<algorithm> #define maxn 500 using namespace std; int block[24]; int roller[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 back[8]={5,4,7,6,1,0,3,2}; int goalpos[8] = {6,7,8,11,12,15,16,17}; int op[100000]; int rot(int *blk,int dir){ for(int i=1;i<7;i++){ int tmp = blk[roller[dir][i]]; blk[roller[dir][i]] = blk[roller[dir][i-1]]; blk[roller[dir][i-1]]=tmp; } } int dfs(int d,int maxd){ if(d == maxd){ int ok=1; for(int i=1;i<8;i++){ if(block[goalpos[i]]!=block[goalpos[i-1]]){ ok=0; break; } } if(ok){ if(!d){ printf("No moves needed\n%d\n",block[6]); return 1; } for(int i=0;i<d;i++) printf("%c",op[i]+'A'); printf("\n%d\n",block[6]); return 1; } return 0; } else { int diff=0; int a=0,b=0,c=0; for(int i=0;i<8;i++){ if(block[goalpos[i]]==1) a++; if(block[goalpos[i]]==2) b++; if(block[goalpos[i]]==3) c++; } diff = 8-max(max(a,b),c); if(d + diff > maxd) return 0; for(int i=0;i<8;i++){ op[d]=i; rot(block,i); if(dfs(d+1,maxd)) return 1; rot(block, back[i]); } } return 0; } int main() { while(1) { for(int i=0;i<24;i++){ scanf("%d",&block[i]); if(!block[i]) return 0; } for(int maxd=0;;maxd++){ if(dfs(0,maxd)){ break; } } } return 0; }
时间: 2024-10-24 13:02:13