zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    gost源码分析心得
    go语言net编程,设置TCP连接发出使用源IP
    代理程序gost使用
    squid关闭缓存
    shell中的if比较
    10年以上年化20%以上收益率的基金经理
    股票信息查询
    02.win2003虚拟机安装和dos命令
    01.网络安全和虚拟机
    部署kali渗透环境
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4499420.html
Copyright © 2011-2022 走看看