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;    
}
posted @ 2016-05-10 17:20  invoid  阅读(170)  评论(0编辑  收藏  举报