10085 - The most distant state
类似8数码的一道题,只是求变化次数最多的一种,也就是队列最后一层
用的bfs+map,map保存方向和这个节点的权值,懒得搞hash函数,就用map顺便当做hash用了
用字符串s存状态,s[9]表示0的位置
最后的方向dfs输出。
这题WA了一次,输出忘加case了……
/* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <cstdio> #include <cstring> #include <map> #include <queue> using namespace std; const int dir[4][2]={-1,0,0,-1,1,0,0,1}; const char d[4]={'U','L','D','R'}; map<string,pair<int,int> > vis; queue<string> q; char f[11]; void output(string s) { int next,i; i=vis[s].second; if(i==-1)return; i=(i+2)%4; next=s[9]+3*dir[i][0]+dir[i][1]; swap(s[s[9]],s[next]); s[9]=next; output(s); i=(i+2)%4; printf("%c",d[i]); return; } int main() { int T,S=0,i,j,k,x,y,tx,ty,now,next,step; string s; scanf("%d",&T); while(T--) { vis.clear(); f[9]=f[10]='\0'; while(!q.empty())q.pop(); for(k=0;k<=8;k++) { scanf("%d",&i); f[k]=i+'0'; if(f[k]=='0')f[9]=k; } vis[f]=make_pair(1,-1); q.push(f); while(!q.empty()) { s=q.front();q.pop(); now=s[9];step=vis[s].first+1; x=now/3;y=now%3; for(i=0;i<4;i++) { tx=x+dir[i][0];ty=y+dir[i][1]; if(tx<0||tx>=3||ty<0||ty>=3)continue; next=tx*3+ty; swap(s[now],s[next]); s[9]=next; if(!vis.count(s)){vis[s]=make_pair(step,i);q.push(s);} swap(s[now],s[next]); } } s[9]=now; printf("Puzzle #%d\n",++S); for(i=0,k=0;i<3;i++) for(j=0;j<3;j++) { printf("%c",s[k++]); if(j!=2)printf(" "); else puts(""); } output(s); puts("\n"); } return 0; }