题意:有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;
}