POJ2632 Crashing Robots 模拟题

题目大意:在一个a×b的仓库里有n个机器人,编号为1到n。现在给出每一个机器人的坐标和它所面朝的方向,以及m条指令,每条指令由三部分组成:整数num代表该条指令调用的机器人的编号;字符act表示操作:其中L表示原地向左转90°,R表示原地向右转90°,F表示向前走一步;整数rep表示执行该条指令的次数。已知,当两个机器人坐标相同时他们会相撞,某一个机器人走出仓库也会撞到墙,问你能否安全执行这m条指令,如果能则输出“OK”;否则输出中断原因(哪两个机器人相撞,或是哪个机器人撞到墙了)。



分析:刚开始理解错了,把L和R当成向左走和向右走了,纠结了一整天.....第二天才发现问题=_=!

典型的模拟题,我们把E,N,W,S这四个方向分别用0,1,2,3代替,同时设一个方向数组dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};如果要左转,只需让当前机器人的方向变量+1即可(对于3+1,我们令其等于0);右转的话就让方向变量-1(同理,对于0-1,我们令其等于3),然后就可以用加一减一来代替复杂的方向判断了。

实现代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef struct node
{
    int x,y,dir;
}robit;
robit r[110];
bool s[110][110];
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int a,b,n,m;
int num[110],rep[110];
char act[110];
bool judge(int x,int y)
{
    if(x<1||x>a||y<1||y>b)
      return true;
    return false;
}
void solve()
{
    int x,y;
    for(int i=1;i<=m;i++)
    {
        bool flag=true;
        if(act[i]=='F')
        {
            s[r[num[i]].x][r[num[i]].y]=false;
            while(rep[i]--)
            {
                x=r[num[i]].x+dir[r[num[i]].dir][0];
                y=r[num[i]].y+dir[r[num[i]].dir][1];
                if(judge(x,y))
                {
                    printf("Robot %d crashes into the wall\n",num[i]);
                    flag=false;
                    break;
                }
                if(s[x][y])
                {
                    int k;
                    for(k=1;k<=n;k++)
                      if(r[k].x==x&&r[k].y==y) break;
                    printf("Robot %d crashes into robot %d\n",num[i],k);
                    flag=false;
                    break;
                }
                r[num[i]].x=x;
                r[num[i]].y=y;
                r[num[i]].dir=r[num[i]].dir;
            }
            s[x][y]=true;
        }
        rep[i]%=4;
        if(act[i]=='R')
          while(rep[i]--)
          {
              int mov=r[num[i]].dir-1;
              if(mov==-1)  mov=3;
              r[num[i]].dir=mov;
          }
        if(act[i]=='L')
          while(rep[i]--)
          {
              int mov=r[num[i]].dir+1;
              if(mov==4)  mov=0;
              r[num[i]].dir=mov;
          }
          if(!flag) break;
          if(i==m) printf("OK\n");
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        char ch;
        memset(s,0,sizeof(s));
        scanf("%d%d",&a,&b);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            cin>>r[i].x>>r[i].y>>ch;
            s[r[i].x][r[i].y]=true;
            if(ch=='E') r[i].dir=0;
            if(ch=='N') r[i].dir=1;
            if(ch=='W') r[i].dir=2;
            if(ch=='S') r[i].dir=3;
        }
        for(int i=1;i<=m;i++)
          cin>>num[i]>>act[i]>>rep[i];
        solve();
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值