题目链接:http://poj.org/problem?id=2286
IDA*对于最优解层数小,每次扩展状态多的时候是一个杀手锏啊。IDA*就是一个加了层数限制depth的DFS,超过了限制就不在搜索下去,如果在当前层数没有搜到目标状态,就加大层数限制depth,这里还只是一个IDA算法,并不是A*的。当然我们可以用A*的估计函数去剪枝,如果当前深度d+h()>depth的时候就可以不再搜索下去了,这样就是IDA*了。
对于这道题,我们把状态用一维数组存储,然后对每个元素设定相应的编号:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
并且把每个操作的相应编号用数组存起来就好处理了:
1 //STATUS:C++_AC_313MS_168KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 #include<map> 13 #include<set> 14 using namespace std; 15 //define 16 #define pii pair<int,int> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 #define PI acos(-1.0) 21 //typedef 22 typedef long long LL; 23 typedef unsigned long long ULL; 24 //const 25 const int N=210; 26 const int INF=0x3f3f3f3f; 27 const int MOD=1000007,STA=400010; 28 const LL LNF=1LL<<60; 29 const double EPS=1e-8; 30 const double OO=1e15; 31 const int dx[4]={-1,0,1,0}; 32 const int dy[4]={0,1,0,-1}; 33 //Daily Use ... 34 template<class T> inline T Min(T a,T b){return a<b?a:b;} 35 template<class T> inline T Max(T a,T b){return a>b?a:b;} 36 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);} 37 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);} 38 //End 39 40 char op[]="ABCDEFGH"; 41 int ma[8][7]={ 42 0,2,6,11,15,20,22, 43 1,3,8,12,17,21,23, 44 10,9,8,7,6,5,4, 45 19,18,17,16,15,14,13, 46 23,21,17,12,8,3,1, 47 22,20,15,11,6,2,0, 48 13,14,15,16,17,18,19, 49 4,5,6,7,8,9,10, 50 }; 51 int r[]={5,4,7,6,1,0,3,2}; 52 int mid[]={6,7,8,11,12,15,16,17}; 53 int path[N],s[24]; 54 int depth; 55 56 int geth(int s[]) 57 { 58 int i,cnt[]={0,0,0,0}; 59 for(i=0;i<8;i++){ 60 cnt[s[mid[i]]]++; 61 } 62 return 8-Max(cnt[1],cnt[2],cnt[3]); 63 } 64 65 void move(int op) 66 { 67 int i,t; 68 t=s[ma[op][0]]; 69 for(i=1;i<7;i++){ 70 s[ma[op][i-1]]=s[ma[op][i]]; 71 } 72 s[ma[op][6]]=t; 73 } 74 75 int idastar(int d) 76 { 77 if(d>=depth)return 0; 78 int i,h; 79 for(i=0;i<8;i++){ 80 move(i); 81 path[d]=i; 82 h=geth(s); 83 if(!h)return 1; 84 if(d+h<depth && idastar(d+1))return 1; 85 move(r[i]); 86 } 87 return 0; 88 } 89 90 int main() 91 { 92 // freopen("in.txt","r",stdin); 93 int i; 94 while(~scanf("%d",&s[0]) && s[0]) 95 { 96 for(i=1;i<24;i++) 97 scanf("%d",&s[i]); 98 depth=geth(s); 99 if(!depth){ 100 printf("No moves needed\n%d\n",s[mid[0]]); 101 } 102 else { 103 while(!idastar(0))depth++; 104 for(i=0;i<depth;i++){ 105 printf("%c",op[path[i]]); 106 } 107 printf("\n%d\n",s[mid[0]]); 108 } 109 } 110 return 0; 111 }