zoukankan      html  css  js  c++  java
  • 洛谷P1126《机器人搬重物》

    原更新日期:2019-01-10 22:06:16

    机器人有直径

    题目描述

    机器人移动学会(RMI)现在正尝试用机器人搬运物品。机器人的形状是一个直径(1.6)米的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个(N imes M)的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:向前移动(1)步(Creep);向前移动(2)步(Walk);向前移动(3)步(Run);向左转(Left);向右转(Right)。每个指令所需要的时间为(1)秒。请你计算一下机器人完成任务所需的最少时间。

    输入输出格式

    输入格式

    第一行为两个正整数(N,M(N,M le 50)),下面(N)行是储藏室的构造,(0)表示无障碍,(1)表示有障碍,数字之间用一个空格隔开。接着一行有(4)个整数和(1)个大写字母,分别为起始点和目标点左上角网格的行与列,起始时的面对方向(东(E),南(S),西(W),北(N)),数与数,数与字母之间均用一个空格隔开。终点的面向方向是任意的。

    输出格式:
    一个整数,表示机器人完成任务所需的最少时间。如果无法到达,输出(−1)

    输入输出样例

    输入样例

    9 10
    0 0 0 0 0 0 1 0 0 0
    0 0 0 0 0 0 0 0 1 0
    0 0 0 1 0 0 0 0 0 0
    0 0 1 0 0 0 0 0 0 0
    0 0 0 0 0 0 1 0 0 0
    0 0 0 0 0 1 0 0 0 0
    0 0 0 1 1 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0
    1 0 0 0 0 0 0 0 1 0
    7 2 2 7 S
    

    输出样例

    12
    

    解题思路

    1. 将格子图转为点图 & 障碍物判断

    要注意这个机器人是有直径的,所以边界和障碍物的四周都不能走

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            int ttt;
            scanf("%d", &ttt);
            if (ttt) {
                map[i][j] = map[i][j - 1] = map[i - 1][j] = map[i - 1][j - 1] = 1;
            }
        }
    }
    
    

    2.单向 BFS
    枚举所有的步数和方向

    3.三维数组判重
    要注意本题是有方向的,所以vis数组需要开三维(vis[N][M][方向]

    代码实现

    /* -- Basic Headers -- */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    
    /* -- STL Iterators -- */
    #include <vector>
    #include <string>
    #include <stack>
    #include <queue>
    
    /* -- External Headers -- */
    #include <map>
    #include <cmath>
    
    /* -- Defined Functions -- */
    #define For(a,x,y) for (int a = x; a <= y; ++a)
    #define Forw(a,x,y) for (int a = x; a < y; ++a)
    #define Bak(a,y,x) for (int a = y; a >= x; --a)
    
    namespace FastIO {
        
        inline int getint() {
            int s = 0, x = 1;
            char ch = getchar();
            while (!isdigit(ch)) {
                if (ch == '-') x = -1;
                ch = getchar();
            }
            while (isdigit(ch)) {
                s = s * 10 + ch - '0';
                ch = getchar();
            }
            return s * x;
        }
        inline void __basic_putint(int x) {
            if (x < 0) {
                x = -x;
                putchar('-');
            }
            if (x >= 10) __basic_putint(x / 10);
            putchar(x % 10 + '0');
        }
        
        inline void putint(int x, char external) {
            __basic_putint(x);
            putchar(external);
        }
    }
    
    
    namespace Solution {
        const int dx[] = { 0, 1, 0, -1 };
        const int dy[] = { 1, 0, -1, 0 };
        const int MAXN_M = 50 + 10;
        
        struct Robot {
            int x, y;
            int dir;
            int step;
        };
        
        std::queue<Robot> q;
        
        bool vis[MAXN_M][MAXN_M][4];
        bool map[MAXN_M][MAXN_M];
        
        int n, m;
        int startx, starty, endx, endy, sd;
        
        char startdir;
    }
    
    signed main() {
    #define HANDWER_FILE
    #ifndef HANDWER_FILE
        freopen("testdata.in", "r", stdin);
        freopen("testdata.out", "w", stdout);
    #endif
        using namespace Solution;
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                int ttt;
                scanf("%d", &ttt);
                if (ttt) {
                    map[i][j] = map[i][j - 1] = map[i - 1][j] = map[i - 1][j - 1] = 1;
                }
            }
        }
        scanf("%d %d %d %d %c", &startx, &starty, &endx, &endy, &startdir);
        switch(startdir) {
            case 'E': {
                sd = 0;
                break;
            }
            case 'S': {
                sd = 1;
                break;
            }
            case 'W': {
                sd = 2;
                break;
            }
            default: {
                sd = 3;
                break;
            }
        } // 对方向进行处理
        if (startx >= n || startx < 1 || starty >= m || starty < 1 || map[startx][starty]) {
            puts("-1");
            return 0;
        }
        Robot rb;
        rb.x = startx;
        rb.y = starty;
        rb.dir = sd;
        rb.step = 0;
        vis[startx][starty][sd] = true;
        q.push(rb);
        // 开始 BFS
        while (!q.empty()) {
            rb = q.front();
            q.pop();
            int newx = rb.x;
            int newy = rb.y;
            if (newx == endx && newy == endy) {
                printf("%d
    ", rb.step);
                return 0;
            }
            // 枚举步数
            for (int steps = 1; steps <= 3; ++steps) {
                newx += dx[rb.dir];
                newy += dy[rb.dir];
                if (newx < 1 || newx >= n || newy < 1 || newy >= m || map[newx][newy]) {
                    break;
                }
                if (!vis[newx][newy][rb.dir]) {
                    vis[newx][newy][rb.dir] = true;
                    Robot nown;
                    nown.x = newx;
                    nown.y = newy;
                    nown.dir = rb.dir;
                    nown.step = rb.step + 1;
                    q.push(nown);
                }
            }
            // 更新步数
            Robot nown = rb;
            ++nown.step;
            --nown.dir;
            if (nown.dir == -1) nown.dir = 3;
            if (!vis[nown.x][nown.y][nown.dir]) {
                vis[nown.x][nown.y][nown.dir] = true;
                q.push(nown);
            }
            nown.dir = rb.dir + 1;
            if (nown.dir == 4) nown.dir = 0;
            if (!vis[nown.x][nown.y][nown.dir]) {
                vis[nown.x][nown.y][nown.dir] = true;
                q.push(nown);
            }
        }
        puts("-1");
        return 0;
    }
    
    
  • 相关阅读:
    centos7安装nginx
    linux经常使用的命令
    linux 安装 VNC
    linux配置yum源
    docker服务器、以及容器设置自动启动
    docker初步学习以及常用命令
    Docker命令详解(run篇)
    Linux scp命令
    Linux常用命令学习31个
    Linux下解压tar.xz文件
  • 原文地址:https://www.cnblogs.com/handwer/p/13816492.html
Copyright © 2011-2022 走看看