uva704 - Colour Hash
链接:Miku
------------------------
思路简单,双向bfs,实现困难
---------------------------
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int maxn=100003; int f,ans1,ans2,head[maxn],nex[maxn],fr[maxn],mov[maxn],step[maxn]; int ansi[maxn][25],si[maxn][25],now[25],goal[24]={0,3,4,3,0,5,6,5,0,1,2,1,0,7,8,7,0,9,10,9,0}; int anhead[maxn],annex[maxn],anfr[maxn],anmov[maxn]; int t; int check(){ for(int i=0;i<=20;++i) if(now[i]!=goal[i]) return 0; return 1; } int cmp(int *a,int *b){ for(int i=0;i<=20;++i) if(a[i]!=b[i]) return 0; return 1; } int hashh(int x){ int s=0; for(int i=1;i<=20;++i){ s=(s*11+si[x][i])%maxn; } return s; } int check2(int x){ int h=hashh(x); int u=anhead[h]; while(u){ if(cmp(ansi[u],si[x])){ ans2=u; return 1; } u=annex[u]; } return 0; } int add(int x){//x状态的所有拓展状态 int h=hashh(x); int u=head[h]; while(u){ if(cmp(si[u],si[x])){ return 0; } u=nex[u]; } nex[x]=head[h];//链表 head[h]=x; return 1; } void bfs(int *x,int now){ int tail=0,front=1; step[0]=0; for(int i=0;i<=20;++i) si[0][i]=x[i]; memset(head,0,sizeof(head)); memset(nex,0,sizeof(nex)); add(0); while(tail<front){ if(now&&check2(tail)){ f=1; ans1=tail; break; } if(step[tail]>8) break; for(int i=0;i<=9;++i) si[front][i+2]=si[tail][i]; si[front][0]=si[tail][10]; si[front][1]=si[tail][11]; for(int i=12;i<=20;++i) si[front][i]=si[tail][i]; if(add(front)){ step[front]=step[tail]+1; mov[front]=1; fr[front]=tail; front++; } for(int i=9;i<=18;++i) si[front][i]=si[tail][i+2]; si[front][19]=si[tail][9]; si[front][20]=si[tail][10]; for(int i=0;i<=8;++i) si[front][i]=si[tail][i]; if(add(front)){ step[front]=step[tail]+1; mov[front]=2; fr[front]=tail; front++; } for(int i=0;i<=9;++i) si[front][i]=si[tail][i+2]; si[front][10]=si[tail][0]; si[front][11]=si[tail][1]; for(int i=12;i<=20;++i) si[front][i]=si[tail][i]; if(add(front)){ step[front]=step[tail]+1; mov[front]=3; fr[front]=tail; front++; } for(int i=9;i<=18;++i) si[front][i+2]=si[tail][i]; si[front][9]=si[tail][19]; si[front][10]=si[tail][20]; for(int i=0;i<=8;++i) si[front][i]=si[tail][i]; if(add(front)){ step[front]=step[tail]+1; mov[front]=4; fr[front]=tail; front++; } tail++; } } void printmov(int x){ if(x){ printmov(fr[x]); printf("%d",mov[x]); } } void anprint(int x){ if(x){ if(anmov[x]==2) printf("4"); else printf("%d",(anmov[x]+2)%4); anprint(anfr[x]); } } int main(){ scanf("%d",&t); bfs(goal,0); memcpy(anhead,head,sizeof(head));//an==从答案 memcpy(annex,nex,sizeof(nex)); memcpy(anfr,fr,sizeof(fr)); memcpy(anmov,mov,sizeof(mov)); memcpy(ansi,si,sizeof(si)); for(int i=1;i<=t;++i){ for(int j=0;j<=23;++j) scanf("%d",&now[j]); if(check()){ cout<<"PUZZLE ALREADY SOLVED\n"; continue; } ans1=ans2=0;//答案坐标 f=0; bfs(now,1); if(f){ printmov(ans1); anprint(ans2); cout<<endl; }else{ cout<<"NO SOLUTION WAS FOUND IN 16 STEPS\n"; } } }