剪枝:每次不要往反方向搜。
注意:長度相同要輸出字典序最小的操作
PS.一開始是用狀態壓縮+BFS的,結果無情的TLE了、、、
估價函數:
int h(int st[])//估價函數{int i,num[4]={0};for(i=0;i<8;i++)num[st[mid[i]]]++;return 8-max(num[1],max(num[2],num[3])); }
CODE:
/*IDA_star*//*注意長度相同要按輸出字典序最小的*//*AC代碼:172ms*/#include <iostream>#include <cstdio>#include <memory.h>#include <algorithm>#include <queue>#include <cstdlib>#include <cstring>#define min(a,b) (a<b?a:b)#define max(a,b) (a>b?a:b)#define INF 1e8#define MAXN 17000000using namespace std;int map[8][7]={//A操作對應的那一列在Map中的下標15,16,3,17,10,18,19,20,21,5,22,12,23,24,7,6,5,4,3,2,1,14,13,12,11,10,9,8,24,23,12,22,5,21,20,19,18,10,17,3,16,15,8,9,10,11,12,13,14,1,2,3,4,5,6,7};int mid[8]={3,4,5,17,22,10,11,12};//中間的座標int fan[8]={5,4,7,6,1,0,3,2};int S[25],start[25],bound,kind;bool ans;int path[MAXN];//記錄路徑char op[9]="ABCDEFGH";void Init(){int i;for(i=2;i<=24;i++)scanf("%d",&S[i]);for(i=1;i<=7;i++)start[i]=S[i+4];for(i=8;i<=14;i++)start[i]=S[i+6];start[15]=S[1];start[16]=S[3];start[17]=S[12];start[18]=S[21];start[19]=S[23];start[20]=S[2];start[21]=S[4];start[22]=S[13];start[23]=S[22];start[24]=S[24];}int h(int st[])//估價函數{int i,num[4]={0};for(i=0;i<8;i++)num[st[mid[i]]]++;return 8-max(num[1],max(num[2],num[3])); }void change(int x){int i,t;t=start[map[x][0]];for(i=0;i<6;i++)start[map[x][i]]=start[map[x][i+1]];start[map[x][6]]=t;}void Out(int a[]){int i;for(i=1;i<=24;i++)printf("%d ",a[i]);printf("\n");}int dfs(int dv,int pre){int i;int hv=h(start);if(hv+dv>bound)return hv+dv;if(hv==0){ans=true;kind=start[3];return dv;}int next_bound=INF;for(i=0;i<8;i++){if(fan[i]==pre) continue;//剪枝//Out(start);change(i);path[dv]=i;int new_bound=dfs(dv+1,i);change(fan[i]);//Out(start);if(ans) return new_bound;next_bound=min(next_bound,new_bound); }return next_bound;}void Print(){int i;for(i=0;i<bound;i++)printf("%c",op[path[i]]);printf("\n");printf("%d\n",kind);}void IDA_star(){ans=false;bound=h(start);while(!ans){bound=dfs(0,-10);}Print();}void Solve(){int v;v=h(start);if(!v){printf("No moves needed\n");printf("%d\n",start[3]);return ;}IDA_star();}int main(){while(scanf("%d",&S[1])!=EOF){if(S[1]==0) break;Init();Solve();}return 0;}