bzoj1054: [HAOI2008]移动玩具
状态空间搜索?用map判重。
#include<cstdio> #include<algorithm> #include<cstring> #include<map> #include<queue> using namespace std; int dx[]={1,0,-1,0},dy[]={0,1,0,-1}; struct Status { int a[4][4]; Status move(int x,int y,int dir) { Status res = *this; if(!a[x][y]) return *this; int nx=x+dx[dir]; int ny=y+dy[dir]; if(nx<0 || nx>3 || ny<0 || ny>3) return *this; if(a[nx][ny]) return *this; res.a[nx][ny]=1; res.a[x][y]=0; return res; } bool operator < (const Status b) const { for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(a[i][j]!=b.a[i][j]) return a[i][j]<b.a[i][j]; return false; } bool operator ==(const Status b) const { for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(a[i][j]!=b.a[i][j]) return false; return true; } void init() { char s[10]; for(int i=0;i<4;i++) { scanf("%s",&s); for(int j=0;j<4;j++) a[i][j]=s[j]-'0'; } } }next,cur,end; map<Status,int> dist; queue<Status> q; int main() { next.init(); end.init(); dist.clear(); dist[next]=1; q.push(next); while(!q.empty()) { cur=q.front(); q.pop(); if(cur==end) { break; } for(int i=0;i<4;i++) for(int j=0;j<4;j++) for(int d=0;d<4;d++) { next=cur.move(i,j,d); if(!dist[next]) { dist[next]=dist[cur]+1; q.push(next); } } } printf("%d\n",dist[end]-1); return 0; }