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

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

题意:

给定一个n*m的方格,机器人推着直径是1.6的球在格子的线上运动。

每一秒钟可以向左转,向右转或者直走1步2步或是3步。

现在给定一个起点和开始的朝向,问走到终点至少要多少时间。

思路:

真是一道狗屎坑题。题目给出的是格点,而机器人是在交点上运动的。

盗用一下洛谷@雒仁韬的图。题目给出的障碍物其实是橙色的四个点中的右下角的这个。

而且由于球的直径,最外围边界并不能走到。如果正确理解了题意的话应该就没问题了。

由于有方向,所以用三维数组来存某点是否被访问。

 

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<map>
  4 #include<set>
  5 #include<iostream>
  6 #include<cstring>
  7 #include<algorithm>
  8 #include<vector>
  9 #include<queue>
 10 
 11 using namespace std;
 12 
 13 int n, m;
 14 int mat[55][55];
 15 //0E, 1S, 2W, 3N
 16 int dx[4][3] = {{0, 0, 0}, {1, 2, 3}, {0, 0, 0}, {-1, -2, -3}};
 17 int dy[4][3] = {{1, 2, 3}, {0, 0, 0}, {-1, -2, -3}, {0, 0, 0}};
 18 bool vis[55][55][5];
 19 struct node{
 20     int x, y;
 21     int dir;
 22     int t;
 23 }st, ed;
 24 
 25 int getdir(char c)
 26 {
 27     if(c == 'E')return 0;
 28     if(c == 'S')return 1;
 29     if(c == 'W')return 2;
 30     if(c == 'N')return 3;
 31 }
 32 
 33 bool check(int i, int j)
 34 {
 35     return (i >= 1 && i < n && j >= 1 && j < m);
 36 }
 37 
 38 int main()
 39 {
 40     scanf("%d%d", &n, &m);
 41     for(int i = 1; i <= n; i++){
 42         for(int j = 1; j <= m; j++){
 43             scanf("%d", &mat[i][j]);
 44             if(mat[i][j]){
 45                 mat[i - 1][j] = 1;
 46                 mat[i][j - 1] = 1;
 47                 mat[i - 1][j - 1] = 1;
 48             }
 49         }
 50     }
 51     
 52     scanf("%d%d%d%d", &st.x, &st.y, &ed.x, &ed.y);
 53     char dir;
 54     //st.x--;st.y--;ed.x--;ed.y--;
 55     getchar();
 56     scanf("%c", &dir);
 57     st.dir = getdir(dir);
 58     st.t = 0;
 59     
 60     queue<node>que;
 61     que.push(st);
 62     vis[st.x][st.y][st.dir] = true;
 63     int ans = -1;
 64     while(!que.empty()){
 65         node now = que.front();que.pop();
 66         //cout<<endl<<now.x<<" "<<now.y<<" "<<now.t<<endl;
 67         if(now.x == ed.x && now.y == ed.y){
 68             ans = now.t;
 69             break;
 70         }
 71         node to;
 72         to.x = now.x;to.y = now.y;to.t = now.t + 1;
 73         to.dir = (now.dir + 1) % 4;
 74         if(!vis[to.x][to.y][to.dir]){
 75             vis[to.x][to.y][to.dir] = true;
 76             que.push(to);
 77         }
 78         to.dir = (now.dir - 1 + 4) % 4;
 79         if(!vis[to.x][to.y][to.dir]){
 80             vis[to.x][to.y][to.dir] = true;
 81             que.push(to);
 82         }
 83         
 84         to.dir = now.dir;
 85         for(int i = 0; i < 3; i++){
 86             to.x = now.x + dx[to.dir][i];
 87             to.y = now.y + dy[to.dir][i];
 88             if(mat[to.x][to.y])break; 
 89             if(check(to.x, to.y) && !vis[to.x][to.y][to.dir]){
 90                 vis[to.x][to.y][to.dir] = true;
 91                 que.push(to);
 92                 //cout<<to.x<<" "<<to.y<<" "<<to.t<<endl;
 93             }
 94         }
 95     }
 96     
 97     cout<<ans<<endl;
 98         
 99     return 0;
100 }

 

转载于:https://www.cnblogs.com/wyboooo/p/10351545.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值