还是那句话,解题先看题。由题意知有一根长度为L的木棒,木棒上面有n只蚂蚁,每只蚂蚁或朝左或朝右且以每秒1cm的速度移动,吗,蚂蚁相撞后掉头,问T秒后每只蚂蚁的状态(按输入顺序输出)。
由题解题,因为每个蚂蚁相遇后都会掉头所以我们首先发现他们的相对位置是固定的不变的,其次我们注意到两只蚂蚁相遇后再调头后的位置与蚂蚁直接穿过对方的位置相同,只是两种情况下相同位置下是不同蚂蚁。所以我们可以列出以下等式
相撞调头后A位置=相撞穿过后B位置,相撞调头后B位置=相撞穿过后A位置
所以我们可以从这里做手脚求出T秒之后所有蚂蚁的位置记录在一个数组里——是不是觉得很正确?错了,因为输出还要求把方向一并输出来,所以这只完成了部分功能,为了把方向一并输出我们(至少我是如此)可以自定义结构体封装属性或者定义两个数组。然后根据相对位置不变把属性值一 一赋给记录蚂蚁信息的结构体数组M。另外按顺序输出不知大家还记不记得,我们可以加一个属性id来匹配录入顺序。重排序后输出(注意每个案例结束后要加一行空行)
附上AC代码 Run Time 0.020
#include<cstdio>
#include<map>
#include<algorithm>
#include<cstring>
using namespace std;
int T,L,n;
const int MAXM=1000000;
const int MAXN=10000+10;
int vis[MAXM];
struct Pos
{
int x;
char dir;
}pos[MAXN];
struct Node
{
int id;
int x;
char dir;
}M[MAXN];
int cmp(struct Node s1,struct Node s2)
{
return s1.x<s2.x;
}
int cmp2(struct Node s1,struct Node s2)
{
return s1.id<s2.id;
}
int cmp3(struct Pos s1,struct Pos s2)
{
return s1.x<s2.x;
}
int main()
{
int Test;
scanf("%d",&Test);
for(int kase=1;kase<=Test;kase++)
{
map<int,int> m;
scanf("%d%d%d",&L,&T,&n);
for(int i=0;i<n;i++) { scanf("%d %c",&M[i].x,&M[i].dir); M[i].id=i; }
sort(M,M+n,cmp);
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
if(M[i].dir=='L') { pos[i].x=M[i].x-T; pos[i].dir=M[i].dir; }
else if(M[i].dir=='R') { pos[i].x=M[i].x+T; pos[i].dir=M[i].dir; }
if(m.count(pos[i].x)==0) m[pos[i].x]=1;
else if(m.count(pos[i].x)>0) m[pos[i].x]++;
}
sort(pos,pos+n,cmp3);
for(int i=0;i<n;i++)
{
M[i].x=pos[i].x;
M[i].dir=pos[i].dir;
}
sort(M,M+n,cmp2);
printf("Case #%d:\n",kase);
for(int i=0;i<n;i++)
{
if(M[i].x<0 || M[i].x>L) printf("Fell off\n");
else if(m[M[i].x]>1) printf("%d Turning\n",M[i].x);
else printf("%d %c\n",M[i].x,M[i].dir);
}
printf("\n");
}
return 0;
}