本题关键把握两点。
1.所有蚂蚁从左到右的顺序,是固定的,因为所有蚂蚁的左右的蚂蚁相当于两面墙,碰撞后马上反弹,所以相对位置总是保持不变。
2.所有蚂蚁可以看做等价的两个质点,这样当碰撞后,可以看做相互穿透继续一各自的方向前进,则可以求出所有蚂蚁质点在时间T后处在的所处的位置 pos + (-)v*t(1)。
只要把每一个质点和蚂蚁对应起来就可以了。
由1所有蚂蚁最终的位置,是从左到右升序排列的。所以只需要将所有按公式(1)计算过的结果按位置升序排序,就可以获得从左到右蚂蚁的位置。
本题要求按照原来输入的顺序,输出。由于输入结果不一定是按从左到右输入。要先排序,排序后的序列就是从左到右的蚂蚁的顺序,用一个数组记录从左到右第i只蚂蚁的输入序号,具体做法:将排序后蚂蚁的输入序号(代码中结构体的id,在输入时记录)所在下标的值赋为从左到右的编号,在输出的时候按记录的顺序输出。
[code:]
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 10000+5;
struct Ant
{
int id,pos,dirc;
bool operator < (const Ant& a)const
{
return pos < a.pos;
}
};
int main()
{
int ks,l,t,n,kase = 1;
Ant ants[MAX];
int order[MAX];
scanf("%d",&ks);
while(ks--)
{
scanf("%d %d %d",&l,&t,&n);
int d,p;
char dir;
for(int i =0; i < n; i++)
{
scanf("%d %c",&p,&dir);
d = (dir == 'L' ? -1 : 1);
ants[i] = (Ant){i,p,d};
}
sort(ants, ants + n);
for(int i = 0; i < n; i++)//记录第i次输入的对应的从左到右的蚂蚁的编号
order[ants[i].id] = i;
for(int i = 0; i < n; i++)
{
ants[i].pos = ants[i].dirc < 0 ? ants[i].pos - t : ants[i].pos + t;
}
sort(ants, ants + n);
for(int i = 0; i < n - 1; i++)
{
if(ants[i].pos == ants[i+1].pos)
ants[i].dirc= ants[i+1].dirc = 0;
}
printf("Case #%d:\n",kase++);
for(int i = 0; i < n; i++)
{
p = ants[order[i]].pos;
d = ants[order[i]].dirc;
if(p < 0 || p > l)
puts("Fell off");
else
{
printf("%d",p);
if(d == -1)puts(" L");
else if(d == 0)puts(" Turning");
else if(d == 1)puts(" R");
}
}
printf("\n");
}
//system("pause");
return 0;
}