BZOJ 1054 [HAOI2008]移动玩具

题目描述

在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动
时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移
动到某人心中的目标状态。

输入

前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。接着是一个空
行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。

输出

一个整数,所需要的最少移动次数。

样例输入

1111
0000
1110
0010

1010
0101
1010
0101

样例输出

4
这题看一下就是状压其实,,但是我当时比较蠢,用的dfsT掉了,而我就是傻到没有用bfs,这题可以说是这4题中最水的一个。。。

因为步数不会很多,所以16位bit压一下,bfs水之

code

#include <iostream>
#include <cstring>
#include <stdio.h>
#include <queue>
#define ALL (1<<16)
using namespace std;
int now,to;
bool vis[ALL];
typedef pair<int,int>pa;
 
 
int  bfs(){
    queue<pa>q;
    pa x = make_pair(now,0);
    q.push(x);
    while(!q.empty()){
        pa k = q.front();q.pop();
        if(k.first==to)return k.second;
        if(vis[k.first])continue;
        vis[k.first]=1;
        for(int i=0;i<16;i++){
            if(((1<<i)&(k.first))==0)continue;
            if(i-4>=0&&(((k.first)&(1<<(i-4)))==0)){
                pa y = k;
                y.first^=1<<i;y.first|=1<<(i-4);
                y.second++;
                if(vis[y.first]==0)q.push(y);
            }
            if(i+4<16&&(((k.first)&(1<<(i+4)))==0)){
                pa y = k;
                y.first^=1<<i;y.first|=1<<(i+4);
                y.second++;
                if(vis[y.first]==0)q.push(y);
            }
            int o = (i+1)%4;
            if(o!=0&&(((k.first)&(1<<(i+1)))==0)){
                pa y = k;
                y.first^=1<<i;y.first|=1<<(i+1);
                y.second++;
                if(vis[y.first]==0)q.push(y);
            }
            if(o!=1&&(((k.first)&(1<<(i-1)))==0)){
                pa y = k;
                y.first^=1<<i;y.first|=1<<(i-1);
                y.second++;
                if(vis[y.first]==0)q.push(y);
            }
        }
    }
    return 0;
}
     
int main(){
    //freopen("movea.in","r",stdin);
    //freopen("movea.out","w",stdout);
    for(int i=1;i<=4;i++){
        for(int j=1;j<=4;j++){
            char ch;
            cin >> ch;
            bool x = ch-'0';
            if(x)now|=1<<(4*(i-1)+j-1);
        }
    }
    for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++){
            char ch;
            cin >> ch;
            bool x = ch-'0';
            if(x)to|=1<<(4*(i-1)+j-1);
        }
    printf("%d\n",bfs());
}





posted @ 2017-07-14 20:34  cooook  阅读(115)  评论(0编辑  收藏  举报