题目链接:https://www.luogu.org/problemnew/show/P1126

吐槽:这题很阴险

  • 一开始没把格子图转化成点图:30分

  • 转化成点图,发现样例过不去,原来每步要判断vis数组和step大小,寻找最优解,一块加了上去,以为能AX,结果边界处理不对:50分

  • 加了边界后才AC。

(实际修改过程要坑爹的多orz 这么说吧,从20分到100分我全得过)

言归正传,搞一下这道题

广搜题,思路很好想:用结构体开个队列,分别保存每步的坐标、方向和步数,用vis数组保存当前格子上的最优解,然后开一个ans数组,保存所有能跑到终点的步数,搜完后,从ans中选一个最小的输出。

这是大致的思路,具体实现还有很多细节和坑点。

  1. 输入的格子图要转化成点图,即
for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
      {
          bool a;
          cin>>a;
          if(a)
          {
              map[i][j]=1;
                map[i-1][j-1]=1;
                map[i-1][j]=1;
                map[i][j-1]=1;
            }
        }
  1. 要从点图的周围包上一层“1”,因为边界也是不能走的(多么痛的领悟QAQ)
for(int i=1;i<=n;i++)
{
        map[n][i]=1;
        map[i][m]=1;
}
  1. 要把答案存起来,找一个最小的输出(被我校dalao坑了 QAQ dalaoZZH:“广搜先找到的一定是最优解,所以把这句去了就行”)
if(q[h].x==ex&&q[h].y==ey)
 {
       ans[++tot]=q[h].st;
 }

 for(int i=1;i<=tot;i++)
    {
        if(ans[i]<minl)
           minl=ans[i];
    }
  1. vis数组也要更新成最优解
  if(vis[xx][yy]>step)
  {
      q[++t].x=xx, q[t].y=yy;
      q[t].st=step+1, q[t].dir=i;
      vis[xx][yy]=step;
  }
  1. 方向也要判断好

坑点差不多就这些了,接下来上代码

#include<iostream>
#include<cstring>
using namespace std;
bool map[51][51]; //存地图
int vis[51][51];  //存访问过的最优解
struct yyy{       //队列
    int x,        //坐
        y,        //标
        dir,      //方向
        st;       //步数
}q[5001];
int h=1,t;        //队头、队尾
int ans[5001]={-1},tot,minl=0x7fffff; //处理答案
int fx[5][2]={{0,0},{0,1},{0,-1},{1,0},{-1,0}}; //处理方向
int main()
{
    //输入+预处理地图
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
      {
          bool a;
          cin>>a;
          if(a)
          {
              map[i][j]=1;
              map[i-1][j-1]=1;
              map[i-1][j]=1;
              map[i][j-1]=1;
          }
      }

    for(int i=1;i<=n;i++)
    {
        map[n][i]=1;
        map[i][m]=1;
    }
    int sx,sy,ex,ey;  char sfx;
    cin>>sx>>sy>>ex>>ey>>sfx;

    //预处理搜索
    q[++t].x=sx,q[t].y=sy,q[t].st=0;
    if(sfx=='E')
      q[t].dir=1;
    if(sfx=='W')
      q[t].dir=2;
    if(sfx=='S')
      q[t].dir=3;
    if(sfx=='N')
      q[t].dir=4;
    memset(vis,1,sizeof(vis)); //把vis数组初始化为一个很大的数,"1"实际为16843009(qwq) 

    //搜索
    while(h<=t)
    {
        if(q[h].x==ex&&q[h].y==ey)
        {
            ans[++tot]=q[h].st;
        }

        for(int i=1;i<=4;i++) //向四个方向搜索
        {
            int step=q[h].st;
            if(i!=q[h].dir) //如果方向不一样,则需转弯,步数加一
            {
                step=q[h].st+1;
                if((i==1&&q[h].dir==2)||(i==2&&q[h].dir==1)||(i==3&&q[h].dir==4)||(i==4&&q[h].dir==3)) //如果向后转,需要转两次弯
                  step=q[h].st+2;
            }
            for(int j=1;j<=3;j++) //枚举步数
            {
                int xx,yy;
                xx=q[h].x+j*fx[i][0],yy=q[h].y+j*fx[i][1]; //xx、yy为目标点坐标 

                if(xx>n||xx<1||yy>m||yy<=0||map[xx][yy])  //如果越界或有障碍,直接退出循环
                  break;
                if(vis[xx][yy]>step) //保存最优解
                {
                    q[++t].x=xx, q[t].y=yy;
                    q[t].st=step+1, q[t].dir=i;
                    vis[xx][yy]=step;
                }
            }
        }
        h++;
    }
    for(int i=1;i<=tot;i++) //寻找最优答案
    {
        if(ans[i]<minl)
          minl=ans[i];
    }

    //输出
    if(minl<0x7fffff)
      cout<<minl;
    else
      cout<<-1;

    return 0;  //完美结束
}

最后打个广告

我的洛谷博客

我的博客园博客

洛谷 P1126 机器人搬重物 (BFS)的更多相关文章

  1. 洛谷P1126机器人搬重物[BFS]

    题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有些格子为不可移动的障碍.机 ...

  2. 洛谷P1126 机器人搬重物

    洛谷1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格, ...

  3. 洛谷——P1126 机器人搬重物

    P1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有 ...

  4. 洛谷P1126 机器人搬重物【bfs】

    题目链接:https://www.luogu.org/problemnew/show/P1126 题意: 给定一个n*m的方格,机器人推着直径是1.6的球在格子的线上运动. 每一秒钟可以向左转,向右转 ...

  5. 洛谷 P1126 机器人搬重物

    题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径 $1.6 米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个 N×MN \times MN×M ...

  6. 洛谷—— P1126 机器人搬重物

    https://www.luogu.org/problem/show?pid=1126 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机 ...

  7. luogu P1126 机器人搬重物 题解

    luogu P1126 机器人搬重物 题解 题目描述 机器人移动学会(\(RMI\))现在正尝试用机器人搬运物品.机器人的形状是一个直径\(1.6\)米的球.在试验阶段,机器人被用于在一个储藏室中搬运 ...

  8. P1126 机器人搬重物

    P1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有 ...

  9. luogu P1126 机器人搬重物

    题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有些格子为不可移动的障碍.机 ...

随机推荐

  1. HDU3555【数位DP】

    入门...还在学习中,先贴一发大牛博客 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题目大意: 给一个数字n,范围在1~2^63-1,求1~ ...

  2. bzoj 2395: [Balkan 2011]Timeismoney【计算几何+最小生成树】

    妙啊,是一个逼近(?)的做法 把两个值最为平面上的点坐标,然后答案也是一个点. 首先求出可能是答案的点xy分别是按照c和t排序做最小生成树的答案,然后考虑比这两个点的答案小的答案,一定在xy连线靠近原 ...

  3. [Xcode 实际操作]一、博主领进门-(1)iOS项目的创建和项目模板的介绍

    目录:[Swift]Xcode实际操作 本文将演示iOS项目的创建和项目模板的介绍. [Create a new Xcode project]创建一个新的项目. 在弹出的模板窗口中,显示了所有的项目模 ...

  4. [Xcode 实际操作]一、博主领进门-(12)代码重构

    目录:[Swift]Xcode实际操作 本文将演示如何重构代码. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] [快速更改同名变量或常量] 在代码编辑区域,点击需 ...

  5. [Xcode 实际操作]一、博主领进门-(13)在控制台的几种打印输出语句和po命令

    目录:[Swift]Xcode实际操作 本文将演几种在控制台输出日志的方式. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit class ...

  6. AVAudioPlayer 如何在页面呈现之后按需初始化

    在页面中按需初始化 AVAudioPlayer 很多时候我们需要根据页面上内容的情况创建 AVAudioPlayer 对象,已达到降低无谓资源占用等目的.下面我们来看一段代码看起来正确的代码: ove ...

  7. 《ERP真的免费不花钱·企业自主实施OdooERP》试读:第十章-仓库条码操作案例

    文/开源智造联合创始人老杨 本文来自<企业自主实施OdooERP>的试读章节.书籍尚未出版,请勿转载.欢迎您反馈阅读意见. 案例背景 各位读者同学,本案例假定读者已经完成了进销存案例练习. ...

  8. java的无序机制

    简单说一下上面提到的无序写,这是jvm的特性,比如声明两个变量,String a; String b; jvm可能先加载a也可能先加载b.同理,instance = new Singleton();可 ...

  9. 转 载python数据分析(1)-numpy产生随机数

    转自:http://blog.csdn.net/jinxiaonian11/article/details/53143141 在数据分析中,数据的获取是第一步,numpy.random 模块提供了非常 ...

  10. mac 终端查看端口命令

    查看 端口所在线程 lsof -i:8080 mac-abeen:spider abeen$ lsof -i:8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF ...