HDU Tobo or not Tobo (IDA*)
继续IDA*搜索,估价函数H仍然是曼哈顿距离,每一次转换会改变4个位置的曼哈顿距离,分别改变1,所以把曼哈顿距离和+3/4便可以作为H函数,表示至少需要多少步,一个DFS的剪枝。
这题最多九步,BFS应该也无压力
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[9]; int depth,flag; char str[10]; int rotation[4][4]={{0,1,4,3},{1,2,5,4},{3,4,7,6},{4,5,8,7}}; int abs(int x){ return x<0?-x:x; } int H(int *b){ int ans=0; for(int i=0;i<9;i++) ans+=abs(i/3-(b[i]-1)/3)+abs(i%3-(b[i]-1)%3); return (ans+3)/4; } void change(int *b,int k){ if(k&1){ //顺时针旋转 k>>=1; int tmp=b[rotation[k][3]]; for(int i=3;i>0;i--) b[rotation[k][i]]=b[rotation[k][i-1]]; b[rotation[k][0]]=tmp; }else{ //逆时针旋转 k>>=1; int tmp=b[rotation[k][0]]; for(int i=1;i<4;i++) b[rotation[k][i-1]]=b[rotation[k][i]]; b[rotation[k][3]]=tmp; } } void IDAstar(int *b,int curDepth,int dir){ if(flag) return ; if(H(b)>curDepth) return ; if(curDepth==0 && H(b)==0){ flag=1; return ; } for(int i=0;i<8;i++){ if(dir!=-1 && dir/2==i/2 && (dir%2)^(i%2)) continue; int tmp[9]; for(int j=0;j<9;j++) tmp[j]=b[j]; change(tmp,i); IDAstar(tmp,curDepth-1,i); } } int main(){ //freopen("input.txt","r",stdin); int cases=0; while(~scanf("%s",str) && strcmp(str,"0000000000")){ int t=str[0]-'0'; for(int i=0;i<9;i++) a[i]=str[i+1]-'0'; flag=0; for(depth=H(a);depth<=t;depth++){ IDAstar(a,depth,-1); if(flag){ printf("%d. %d\n",++cases,depth); break; } } if(!flag) printf("%d. -1\n",++cases); } return 0; }优质内容筛选与推荐>>