• 【NOIP模拟】箱子


    【问题描述】 有个桌子长 R 宽 C,被分为 R*C 个小方格。其中,一些方格上有箱子,一些方格上有 按 钮,一些方格上有障碍物,一些方格上是空地。现在有个任务,需要把所有箱子推到这 些按 钮上面。箱子有个特征,只能推不能搬不能拉。现在需要用最少的步数把所有箱子推 到按钮 上。 当然,箱子和人都只能以格子为单位移动,不存在一部分在格内一部分在格外 的情况; 只能向四个方向推,箱子和推箱子的队员都不能穿越障碍物。推动的定义是,人 的前进方向 被箱子挡住,且箱子在顺着前进方向的下一格不是箱子或者障碍物,那么就可 以推着箱子和 箱子一起前进一步。

    【输入文件】 输入第一行有两个整数 R,C(4<=R,C<=7),代表桌子的长和宽,接下来一共有 R 行, 每行有 C 个字符。 字符的含义: 0:代表空地 1:代表障碍物 2:代表箱子 3:代表按钮 4:人所在的初始地方 输入数据保证障碍物环绕整个地图,箱子数目跟按钮数目相同,箱子最少有一个,不 会 超过 3 个,队员肯定只有一个。不用考虑箱子初始就按着按钮的情况。保证有解

    【输出文件】 输出只有一行,为解决机关的最小步数。

    【输入样例】 4 5 11111 14231 10231 11111

    【输出样例】 4

    【样例说明】 在样例中,最快的方法之一是先向东把第一个箱子推到按钮上,然后向西走 回原处,之 后向南一步,再向东推第二个箱子到按钮上。至此任务完成,共使用了 4 步。 【数据范围】 对 30%的输入数据 :箱子只有一个。 对 100%的输入数据 :4<=R,C<=7。

    分析:测试t2,心态不好,没敢调

    bfs+储存状态

    首先我们将每个位置重新编号

    用f[person][box1][box2][box3]来存储现在的状态,即人在person处,三个箱子分别在box1,box2,box3处的状态移动的最小步数。

    先扩展人的移动(人不碰到箱子时),再扩展人与箱子一起的移动

    #include<bits/stdc++.h>
    using namespace std;
    #define N 51
    int n,m,cnt,t1,t2,sx,sy;
    int e[N][N],pos[N][N];
    int f[N][N][N][N];
    int dx[5]={0,0,0,1,-1};
    int dy[5]={0,1,-1,0,0};
    int box[N],button[N],cx[N],cy[N],ope[N];
    bool vis[N][N];
    char c[N];
    struct email
    {
        int person,box1,box2,box3;
    }st;
    email makepair(int x,int y,int w,int z)
    {
        email a;
        a.person=x;a.box1=y;a.box2=w;a.box3=z;
        return a;
    }
    queue<email>que;
    int main()
    {
        scanf("%d%d",&n,&m);
        memset(f,-1,sizeof(f));
        memset(vis,true,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            scanf("%s",c);
            for(int j=1;j<=m;j++)
            {
           
                e[i][j]=c[j-1]-'0';
                pos[i][j]=++cnt;
                cx[cnt]=i;cy[cnt]=j;
                if(e[i][j]==4){sx=i,sy=j;e[i][j]=0;}
                if(e[i][j]==2)box[++t1]=pos[i][j];
                if(e[i][j]==3)button[++t2]=pos[i][j];    
                if(e[i][j]==1)vis[i][j]=false;    
            }
        }
        f[pos[sx][sy]][box[1]][box[2]][box[3]]=0;
        st.person=pos[sx][sy];st.box1=box[1];st.box2=box[2];st.box3=box[3];
        que.push(st);
        while(!que.empty())
        {
            email u=que.front();que.pop();
            int ps=u.person,b1=u.box1,b2=u.box2,b3=u.box3;
            int x0=cx[ps],y0=cy[ps];
            
            int x1=cx[b1],y1=cy[b1];
            int x2=cx[b2],y2=cy[b2];
            int x3=cx[b3],y3=cy[b3];
            vis[x1][y1]=false;vis[x2][y2]=false;vis[x3][y3]=false;
            if(b1==button[1]&&b2==button[2]&&b3==button[3])
            {
                printf("%d",f[ps][b1][b2][b3]);
                return 0;
            }
            int num=f[ps][b1][b2][b3];
            for(int i=1;i<=4;i++)
            {
                int p=x0+dx[i],q=y0+dy[i];
    
               if(p<1||p>n||q<1||q>m)continue;
                if(vis[p][q]&&f[pos[p][q]][b1][b2][b3]==-1)
                {
                    f[pos[p][q]][b1][b2][b3]=num+1;
                    que.push(makepair(pos[p][q],b1,b2,b3));
                }
                ope[1]=b1,ope[2]=b2,ope[3]=b3;
                if(pos[p][q]==ope[2])swap(ope[1],ope[2]);
                if(pos[p][q]==ope[3])swap(ope[3],ope[1]);
                if(pos[p][q]==ope[1])
                {             
                    int pp=p+dx[i],qq=q+dy[i];
                    if(pp<1||pp>n||qq<1||qq>m||!vis[pp][qq])continue;
                    ope[1]=pos[pp][qq];
                    for(int j=1;j<=3;j++)
                        for(int k=j+1;k<=3;k++)
                            if(ope[k]&&ope[k]<ope[j])
                                swap(ope[k],ope[j]);
                    
                    if(f[pos[p][q]][ope[1]][ope[2]][ope[3]]==-1)
                    {
                        f[pos[p][q]][ope[1]][ope[2]][ope[3]]=num+1;
                        que.push(makepair(pos[p][q],ope[1],ope[2],ope[3]));
                    }
                    
                }
            }
            vis[x1][y1]=true;vis[x2][y2]=1;vis[x3][y3]=1;
        }
        return 0;
    }    

    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    Vue学习(十七)修饰符
    组件学习(一)开发组件前必读
    vue学习(十六)“就地更新”策略
    nrm学习(一)
    帧动画的多种实现方式与性能对比
    JavaScript中的二进制对象
    生成式模型与判别式模型
    堡垒机
    vue生产环境nginx配置代理转发跨域
    Ceph nautilus 集群部署
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9440269.html
Copyright © 2020-2023  润新知