[HAOI2008][BZOJ1054] 移动玩具

1054: [HAOI2008]移动玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1277  Solved: 695
[Submit][Status][Discuss]

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

直觉是双向BFS,但是不会写。于是就看了题解,第一次见这样写BFS,感觉好巧妙啊。

数据规模小,但情况种类还是不少的。加上Hash判重(也是才学的),28MS AC。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int t,w,x,y,h,st,en;
bool ans[5][5];
bool flag,mark[66666];
char c;
struct node
{
    bool a[5][5];
    int step;
};
node q[66666];
const int dx[5]={0,-1,0,1,0};
const int dy[5]={0,0,1,0,-1};
int hash(bool a[5][5])
{
    int k=1,s=0;
    for (int i=1;i<=4;i++)
        for (int j=1;j<=4;j++)
        {
            s+=k*a[i][j];
            k<<=1;
        }
    return s;
}
int main()
{
    memset(mark,0,sizeof(mark));
    for (int i=1;i<=4;i++)
    {
        for (int j=1;j<=4;j++)
        {
            c=getchar();
            q[1].a[i][j]=c-‘0‘;
        }
        getchar();
    }
    getchar();
    for (int i=1;i<=4;i++)
    {
        for (int j=1;j<=4;j++)
        {
            c=getchar();
            ans[i][j]=c-‘0‘;
        }
        getchar();
    }
    st=hash(q[1].a);
    en=hash(ans);
    if (st==en) { printf("0"); return 0; }
    mark[st]=1;
    t=0; w=1; q[1].step=0;
    while (t<w)
    {
        t++;
        for (int i=1;i<=4;i++)
            for (int j=1;j<=4;j++)
                if (q[t].a[i][j])
                    for (int k=1;k<=4;k++)
                    {
                        x=i+dx[k];
                        y=j+dy[k];
                        if (x>4||y>4||x<1||y<1||q[t].a[x][y]) continue;
                        swap(q[t].a[i][j],q[t].a[x][y]);
                        h=hash(q[t].a);
                        if (!mark[h])
                        {
                                    if (h==en) { printf("%d",q[t].step+1); return 0; }
                                    w++;
                                    memcpy(q[w].a,q[t].a,sizeof(q[w].a));
                                    q[w].step=q[t].step+1;
                                    mark[h]=true;
                        }
                        swap(q[t].a[i][j],q[t].a[x][y]);
                    }
    }
    return 0;
}
时间: 2024-10-07 08:23:01

[HAOI2008][BZOJ1054] 移动玩具的相关文章

BZOJ1054: [HAOI2008]移动玩具

1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1028  Solved: 555[Submit][Status] Description 在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到某人心中的目标状态. Input 前4行表示玩具的初始状态,每行4个

【bzoj1054】[HAOI2008]移动玩具

题目描述 在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到某人心中的目标状态. 输入 前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具.接着是一个空行.接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上. 输出 一个整数,所需要的最少移动次数. 样例输入 1111 0000 1110 0010 1

BZOJ1054|HAOI2008移动玩具|广搜

Description在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到某人心中的目标状态.Input前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具.接着是一个空行.接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上.Output一个整数,所需要的最少移动次数.Sample Input111100

【BFS】bzoj1054 [HAOI2008]移动玩具

暴搜吧,可以哈希一下,但是懒得写哈希了,所以慢得要死. Code: 1 #include<cstdio> 2 #include<queue> 3 #include<set> 4 #include<algorithm> 5 using namespace std; 6 const int di[]={0,0,-1,1},dj[]={-1,1,0,0}; 7 struct Squ{char S[4][4];}; 8 struct Node{Squ v;int d

BZOJ1055: [HAOI2008]玩具取名

1055: [HAOI2008]玩具取名 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 820  Solved: 482[Submit][Status] Description 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长.现在,他想请你猜猜某一个很长的名字,最初可能是由哪几个字母变形过来的

bzoj 1055 [HAOI2008]玩具取名(区间DP)

1055: [HAOI2008]玩具取名 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1258  Solved: 729[Submit][Status][Discuss] Description 某 人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用 “WING”中任意两个字母代替,使得自己的名字能够扩充得很长.现在,他想请你猜猜某一个很长的名字,最初可能

BZOJ 1054: [HAOI2008]移动玩具( BFS )

一开始没有注意答案为0的情况然后就WA了... 挺水的BFS.. ------------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cctype> #include<iostream>

BZOJ 1055 [HAOI2008]玩具取名

1055: [HAOI2008]玩具取名 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1119  Solved: 653[Submit][Status][Discuss] Description 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长.现在,他想请你猜猜某一个很长的名字,最初可能是由

bzoj1055: [HAOI2008]玩具取名(dp)

1055: [HAOI2008]玩具取名 题目:传送门 简要题意: 就是固定四个字母,给出这四个字母分别可以由哪两个字母组成,然后在给你一个字符串,要求把这个字符串还原成原始的四个字母的其中一个. 题解: 一开始看题有点瞎...想了想是一道超级大难题... 其实就是一个很简单的DP... 定义发f[i][j][s]:表示在字符串中i~j这个区间是否可以组合成为字符s 转移很容易就可以想出来:因为如果f[i][k][s1]==f[k+1][j][s2]==1(i<=k<=j) &&