5
30
2014
0

1054: [HAOI2008]移动玩具

题目:

1054: [HAOI2008]移动玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 898  Solved: 485
[Submit][Status]

Description

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

Input

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

Output

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

Sample Input

1111
0000
1110
0010

1010
0101
1010
0101

Sample Output

4
好吧这道题看上去挺难的……
仔细看一下范围……
4*4的格子……
最多2^16种状态……
好了BFS不解释……
找到每一个1,看看4个方向有没有1,没有就走过去……
加了一点位运算……
于是1A了……
/**************************************************************
    Problem: 1054
    User: sxczf
    Language: C++
    Result: Accepted
    Time:36 ms
    Memory:1976 kb
****************************************************************/
 
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <set>
using namespace std;
inline int maxx(const int &a,const int &b){if (a>b)return a;return b;}
inline int minn(const int &a,const int &b){if (a<b)return a;return b;}
int a,b,c,de,e,f,g,h,i,j,k,l,m,n,s[5],r,now,now2,dis[100005],dl[100005],vis[100005];
char ss[10];
void add(int x){
    c=0;
    c=s[1]*4096+s[2]*256+s[3]*16+s[4];
    if (!vis[c]&&dis[c]>x){
        dis[c]=x;
        vis[c]=1;
        dl[++r]=c;
    }
}
void bfs(){
    memset(dis,0x7f,sizeof(dis));
    l=1;r=1;dl[1]=a;dis[a]=0;vis[a]=1;
    while (l<=r){
        now=dl[l];now2=dl[l];
        s[4]=now%16;
        now/=16;
        s[3]=now%16;
        now/=16;
        s[2]=now%16;
        now/=16;
        s[1]=now%16;
        now/=16;
        for(i=1;i<=4;i++){
            for(j=1;j<=4;j++)
            if (s[i]&(1<<(j-1))){s[i]^=1<<(j-1);
                if (i>1&&!(s[i-1]&(1<<(j-1)))){s[i-1]^=(1<<(j-1));add(dis[now2]+1);s[i-1]^=(1<<(j-1));}
                if (i<4&&!(s[i+1]&(1<<(j-1)))){s[i+1]^=(1<<(j-1));add(dis[now2]+1);s[i+1]^=(1<<(j-1));}
                if (j>1&&!(s[i]&(1<<(j-2)))){s[i]^=(1<<(j-2));add(dis[now2]+1);s[i]^=(1<<(j-2));}
                if (j<4&&!(s[i]&(1<<(j)))){s[i]^=(1<<(j));add(dis[now2]+1);s[i]^=(1<<(j));}
                s[i]^=1<<(j-1);
            }
        }
        l++;
    }
}
int main(){
    for(i=1;i<=4;i++){
        scanf("%s",ss);
        for(j=0;j<=3;j++)
        a=a*2+ss[j]-'0';
    }
    for(i=1;i<=4;i++){
        scanf("%s",ss);
        for(j=0;j<=3;j++)
        b=b*2+ss[j]-'0';
    }
    bfs();
    printf("%d",dis[b]);
    return 0;
}

 

Category: BZOJ | Tags: BFS bzoj | Read Count: 920

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com