PKU 1077-Eight
問題概要
8パズルを解け
解法
最良優先探索で適当な解を探す.最短解じゃなくても良いので簡単.
実装(C++)
#include <queue> #include <stack> #include <algorithm> #include <list> #include <vector> #include <set> #include <map> #include <iostream> using namespace std; typedef long long int lli; typedef unsigned int uint; typedef unsigned char uchar; typedef unsigned long long ull; #define REP(i,x) for(int i=0;i<(int)(x);i++) #define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++) int pow[9]; char d[4]={'l','r','u','d'}; int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1}; struct State{ char MAP[3][3]; int hash; int zx,zy; int md;// void hash_calc(){ hash=0; for(int i=0;i<9;i++){ hash+=MAP[i%3][i/3]*pow[i]; } md=0; for(int x=0;x<3;x++)for(int y=0;y<3;y++){ int tx,ty; if(MAP[x][y]!=0){ tx=(MAP[x][y]-1)%3, ty=(MAP[x][y]-1)/3; }else{ tx=ty=2; } md+=abs(x-tx)+abs(y-ty); } for(int x=0;x<3;x++)for(int y=0;y<3;y++){ if(MAP[x][y]==0){ zx=x;zy=y; } } } bool next(int direction){ int nx=zx+dx[direction],ny=zy+dy[direction]; if(!(nx>=0&&nx<3&&ny>=0&&ny<3))return false; md-=abs(nx-(MAP[nx][ny]-1)%3)+abs(ny-(MAP[nx][ny]-1)/3); md-=abs(zx-2)+abs(zy-2); hash-=MAP[nx][ny]*pow[nx+ny*3]; hash-=MAP[zx][zy]*pow[zx+zy*3]; swap(MAP[nx][ny],MAP[zx][zy]); swap(zx,nx);swap(ny,zy); hash+=MAP[nx][ny]*pow[nx+ny*3]; hash+=MAP[zx][zy]*pow[zx+zy*3]; md+=abs(nx-(MAP[nx][ny]-1)%3)+abs(ny-(MAP[nx][ny]-1)/3); md+=abs(zx-2)+abs(zy-2); return true; } }; bool operator<(const State &a,const State&b){ return a.md>b.md; } ostream &operator<<(ostream &os,const State &a){ REP(y,3){ REP(x,3){ cout<<" "<<(int)a.MAP[x][y]; } cout<<endl; } return os; } map<int,int> ac; map<int,int> back; int main(){ pow[0]=1; for(int i=0;i<8;i++){ pow[i+1]=pow[i]*9; } State start; for(int i=0;i<9;i++){ string tmp; cin>>tmp; if(tmp=="x")tmp="0"; start.MAP[i%3][i/3]=atoi(tmp.c_str()); } //cout<<start<<endl; start.hash_calc(); //cout<<start.hash<<endl; ac[start.hash]=0; priority_queue<State> que; que.push(start); while(!que.empty()){ State st=que.top();que.pop(); //cout<<st<<st.md<<endl; //out<<st.zx<<","<<st.zy<<endl; int now=ac[st.hash]; if(st.md==0){ string res=string(now,' '); for(int i=0;i<now;i++){ res[now-i-1]=d[back[st.hash]]; st.next(back[st.hash]^1); } cout<<res<<endl; return 0; } for(int i=0;i<4;i++){ State next(st); if(next.next(i)){ if(ac.find(next.hash)==ac.end()){ ac[next.hash]=now+1; back[next.hash]=i; que.push(next); } } } } cout<<"unsolvable"<<endl; return 0; }