题意:给出一个N*M的矩阵;
给出A个机器人,B个动作,机器人位于(x,y)并且有一个朝向。
问做完动作时的状况(机器人i撞上墙 或者机器人i撞上机器人j 或者OK)
思路:纯模拟,用一个结构体保存机器人的状态。
注意:看题目的图,会发现这里的矩阵标号和平时做的不一样,下面会有特殊处理。
看这个图,纵向是从大到小的,得处理一下。这应该就是本题最难的地方吧。。。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 205
#define inf 1<<28
using namespace std;
struct kdq
{
int x,y;
int dir;
} point[Max];
int n,m;
int movex[4]= {1,0,-1,0}; //下,左,上,右
int movey[4]= {0,-1,0,1};
int inmap(int x,int y)
{
if(x>0&&y>0&&x<=n&&y<=m)
return 1;
return 0;
}
int visit[Max][Max];
int main()
{
//freopen("acm.txt","r",stdin);
//freopen("ans.txt","w",stdout);
int i,j,k,l,T,x,y,tx,ty;
char a,op;
int num,move;
int robotnum,actionnum;
cin>>T;
while(T--)
{
memset(visit,0,sizeof(visit));
cin>>m>>n;
cin>>robotnum>>actionnum;
for(i=1; i<=robotnum; i++)
{
cin>>x>>y>>a;
point[i].x=n+1-y;//看图会发现他纵向是从大到小的,所以这里得这样处理。
point[i].y=x;
if(a=='S')
point[i].dir=0;
if(a=='N')
point[i].dir=2;
if(a=='E')
point[i].dir=3;
if(a=='W')
point[i].dir=1;
visit[n+1-y][x]=i;//记录这一点机器人的编号
}
bool flag=0;
while(actionnum--)
{
cin>>num>>op>>move;
if(flag)
continue;
if(op=='L')
{
int num1=move%4;
point[num].dir+=(4-num1);
point[num].dir%=4;
//cout<<point[num].dir<<endl;
}
if(op=='R')
{
int num1=move%4;
point[num].dir+=num1;
point[num].dir%=4;
//cout<<point[num].dir<<endl;
}
if(op=='F')
{
x=point[num].x;
y=point[num].y;
int dir=point[num].dir;
//cout<<dir<<endl;
while(move--)
{
tx=x+movex[dir];
ty=y+movey[dir];
//cout<<tx<<" "<<ty<<endl;
//cout<<"visit:"<<visit[tx][ty]<<endl;
if(inmap(tx,ty))//如果没撞墙
{
if(!visit[tx][ty])//如果没撞到机器人,则走到这一个位置。
{
visit[tx][ty]=num;
visit[x][y]=0;
}
else//否则输出撞到机器人
{
printf("Robot %d crashes into robot %d\n",num,visit[tx][ty]);
flag=1;//标记
}
}
else//否则输出撞到墙
{
flag=1;//标记
printf("Robot %d crashes into the wall\n",num);
}
if(flag)//已标记则跳出
break;
x=tx,y=ty;
}
point[num].x=tx;//注意,这一个动作走完之后要更新这个机器人的坐标
point[num].y=ty;
}
}
if(!flag)//如果未标记,则输出OK
cout<<"OK"<<endl;
}
return 0;
}
思路是异常的简单,主要是细心一点写代码。
不过写的还是有点乱,没有仔细优化。