HDU ~ 2300 ~ Crashing Robots (模拟)

题意:有N个机器人在仓库中移动,机器人会按照指令做事,指令有三种“FLR”对应直走,左转,右转,机器人有一个面朝方向“ESWN”,问在执行指令过程中有没机器人撞到墙,或者撞到机器人?

先输入T组测试数据,然后输入地图大小A*B,再输入n和m,表示有n个机器人(编号为1~n)m条指令,输入n个机器人的起始位置和面朝方向,然后输入m条指令,每条指令三个值,i,turn,repeat,第i个机器人,指令(“FLR”),重复次数。

如果机器人%d碰到墙输出“Robot %d crashes into the wall”

如果机器人%d碰到%d输出“Robot %d crashes into robot %d”

如果都没有输出“OK”

思路:对于每个机器人存一下当前位置和朝向。再开一个地图G[MAXN][MAXN]存机器人编号,0表示该点什么也没有,G[x][y]表示在(x,y)处有一个编号为G[x][y]的机器人。然后模拟行走过程,重复repeat次。

对于转向的处理可以采取刘汝佳大佬在UVA ~ 816 ~ Abbott's Revenge (BFS + 打印路径)中的处理方法。对于面朝方向dir,我们用0,1,2,3对应“NESW”(顺序不能乱),对于转向或直走操作用0,1,2表示“FLR”(顺序不能乱),因为输入的是字符所以我们先把他们转化为数字。然后对于左转操作,我们只需要dir = (dir + 3) % 4;就可以得到正确的朝向,对于右转操作dir = (dir + 1) % 4;就可以得到正确的朝向。得到正确朝向后我们把对应的移动数组写出来就可以了:

Dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};(顺序不能乱,因为在对应四个朝向的移动)。

每次走完判断当前位置是否越界(即进入墙中)?是否碰到机器人?如果都没有就把地图G维护一下。

坑点:①注意看图中的坐标系,他的A和B和一般程序中写的是相反的,机器人坐标x,y也是相反的。

              ②机器人的左拐和右拐操作是只在原地转向!!!


#include <bits/stdc++.h>
using namespace std;
const int MAXN = 105;
const char *dirs = "NESW";
const char *turns = "FLR";
const int Dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
int dir_id(char c){ return strchr(dirs, c) - dirs; }//方向ID
int turn_id(char c){ return strchr(turns, c) - turns; }//转向ID
struct Robot
{
    int x, y, dir;//dir的0,1,2,3表示北东南西
}a[MAXN];
int A, B, n, m, G[MAXN][MAXN];
int walk(int id, int turn)
{
    if (turn == 1) a[id].dir = (a[id].dir + 3) % 4;//左转
    if (turn == 2) a[id].dir = (a[id].dir + 1) % 4;//右转
    if (turn != 0) return 0;//不是F就不需要走,只需要转圈
    G[a[id].x][a[id].y] = 0;//取消当前点标记
    a[id].x += Dir[a[id].dir][0]; a[id].y += Dir[a[id].dir][1];
    if (a[id].x <= 0 || a[id].x > A || a[id].y <= 0 || a[id].y > B) return -1;//越界
    if (G[a[id].x][a[id].y] != 0) return G[a[id].x][a[id].y];//机器人碰撞了
    G[a[id].x][a[id].y] = id;//给当前点标记
    return 0;
}
int main()
{
    int T; scanf("%d", &T);
    while(T--)
    {
        memset(G, 0, sizeof(G));
        scanf("%d%d%d%d", &B, &A, &n, &m);
        for(int i = 1; i <= n ; i++)
        {
            char dir; scanf("%d%d %c", &a[i].y, &a[i].x, &dir);
            a[i].dir = dir_id(dir);
            G[a[i].x][a[i].y] = i;
        }
        bool flag = false;
        while (m--)
        {
            int id, step; char turn;
            scanf("%d %c%d", &id, &turn, &step);
            if (flag) continue;
            if (turn != 'F') step %= 4;//转四次相当于没转
            while (step--)
            {
                int ans = walk(id, turn_id(turn));
                if (ans == -1) { flag = true; printf("Robot %d crashes into the wall\n", id); break; }
                if (ans > 0) { flag = true; printf("Robot %d crashes into robot %d\n", id, ans); break; }
            }
        }
        if (flag == false) printf("OK\n");
    }
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值