题意:给出一个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; }
思路是异常的简单,主要是细心一点写代码。
不过写的还是有点乱,没有仔细优化。