1 条题解

  • 0
    @ 2025-8-24 21:42:32

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Horizon20182201
    人间骄阳正好,风过林梢,彼时OI正当年少

    搬运于2025-08-24 21:42:32,当前版本为作者最后更新于2020-07-31 09:06:08,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    这题吸引我的地方竟然是它的题目。。。

    Mud Puddles

    一下我就想到了

    大家都喜欢跳泥坑

    大家都喜欢跳泥坑!!!

    好了我们言归正传

    这题其实是个裸的bfs

    一道很好的练手题

    先来看看题目中的重点:

    “FJ的屋子在平面坐标(0, 0)的位置,贝茜所在的牛棚则位于坐标(X,Y) (-500 <= X <= 500; -500 <= Y <= 500)处。”

    what?负数?USACO您在逗我?

    其实面对负数,我们只要把坐标加上500即可,同时也不要忘记存储地图的数组也要相应增加大小。

    “最少要走多少路才能到贝茜所在的牛棚呢?”

    这。。。说的要多明显有多明显,就差一句“这题请用宽搜解决”。

    “你可以认为从FJ的屋子到牛棚总是存在至少一条不经过任何泥塘的路径。”

    这就是说此题一定有解,无需考虑走不通的情况。

    好的我们先把代码贴上来

    #include<bits/stdc++.h>
    using namespace std;
    
    int X,Y,n,dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};//dir数组存储四个方向
    bool mmap[1005][1005];//存储地图(注意这里不是500而是1000)
    struct node{
        int x,y,sum;
    };//定义结构体,x表示横坐标,y表示纵坐标,sum表示到这个点所需步数
    queue <node> qwq;//当然要符合我们小猪佩奇的可爱气质啦
    
    int bfs ()//宽搜
    {
        while (!qwq.empty())//队列非空
        {
            int xx,yy,s;
            xx=qwq.front().x;
            yy=qwq.front().y;
            s=qwq.front().sum;//取队首元素进行扩展
            for (int i=0;i<4;i++)//4个方向
            {
                int nx=xx+dir[i][0],
                    ny=yy+dir[i][1];//扩展
                if (nx==X && ny==Y)//如果到达目的地
                {
                    while (!qwq.empty())
                      qwq.pop();//清空队列
                    return s+1;//返回值
                }
                else//没有到达目的地
                {
                    if (!mmap[nx][ny])//可以走(即这里不是泥坑)
                    {
                        mmap[nx][ny]=true;//把这里标记成走过的
                        //其实可以再开一个vis数组,但对于这题完全没必要
                        qwq.push({nx,ny,s+1});//入队
                    }
                }
            }
            qwq.pop();//出队
        }
    }
    
    int main()
    {
        scanf ("%d%d%d",&X,&Y,&n);//输入
        memset (mmap,false,sizeof (mmap));//初始化
        X+=500;  Y+=500;//重要!!!一定要加500!!!
        qwq.push({500,500,0});//初始情况入队
        for (int i=1;i<=n;i++)
        {
            int a,b;
            scanf ("%d%d",&a,&b);
            a+=500; b+=500;//坐标加500
            mmap[a][b]=true;//标记泥坑
        }
        printf ("%d\n",bfs ());//输出
        return 0;//完结撒花
    }
    

    另附宽搜模板

    初始状态入队;       
    while(队列不为空)
    {
    	取队首元素进行扩展; 
    	for(对所有可能的拓展状态)
    	{
    		if(新状态合法)
    			入队;
            if(当前状态是目标状态)	
            	处理(输出解或比较解的优劣); 
    	}
    	队首结点扩展完毕,出队; 
    }
    
    
    • 1

    信息

    ID
    1938
    时间
    1000ms
    内存
    125MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者