问题描述:
一根长度为L的木棍上有n只蚂蚁,每只蚂蚁要么往左爬,要么往右爬,速度为1,,当两只蚂蚁相撞时,两者同时掉头,给出每只蚂蚁的初始位置和朝向,计算T秒之后每只蚂蚁的位置和朝向。
输入:第一行为测试样例的书目
每个测试样例先输入一个n 代表n只蚂蚁
随后n行 每行给出蚂蚁的初始位置和朝向
输出:求T秒后各个蚂蚁的位置和朝向 若已经掉落则输出Fell off 若刚好两只蚂蚁相遇则输出Turning
分析:
①不管什么时刻 蚂蚁的相对位置是不变的(可以自己想象一下,两只蚂蚁相遇后不可能穿过对方,所以相对位置不会改变)
②但是宏观上我们可以看做蚂蚁穿过对方继续行走
综上所述,蚂蚁终止时刻的位置是 初始位置 + T * d (d代表方向,-1向左 0 正在转向 1 向右)
那么求出这些终止位置,我们只需要排序,就能确定谁是谁了(因为相对顺序不变)
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100000 + 5
using namespace std;
struct ant
{
int id,position,direct;
// -1 < 0 | 1 >
bool operator < (const ant& A) const
{
return this->position < A.position;
}
};
const char sen[][15] = {"L","Turning","R"};
ant before[maxn];
ant after[maxn];
int order[maxn];
int main()
{
int Case;
scanf("%d",&Case);
int cnt = 0;
while(Case--)
{
int L,T,n;
scanf("%d %d %d",&L,&T,&n);
for(int i = 0;i<n;i++)
{
int t; char p;
scanf("%d %c",&t,&p);
ant a;
a.id = i;
a.position = t;
a.direct = (p=='L' ? -1 : 1);
before[i] = a;
ant b; //预处理出终止蚂蚁和初始蚂蚁
b.id = 0;
b.position = t + T * (p == 'L' ? -1 : 1) ;
b.direct = (p=='L' ? -1 : 1);
after[i] = b;
}
sort(before,before+n);
for(int i = 0;i<n;i++)
{
order[before[i].id] = i; //初始蚂蚁的次序
}
sort(after,after+n); //得到终止序列
for(int i = 0;i<n-1;i++)
{ //正在转向的蚂蚁
if(after[i].position == after[i+1].position) after[i].direct = after[i+1].direct = 0;
}
printf("Case #%d:\n",++cnt);
for(int i = 0;i<n;i++)
{
int a = order[i]; //第i只蚂蚁
if(after[a].position<0 || after[a].position > L )
printf("Fell off\n"); //掉落
else //输出方向和位置
printf("%d %s\n",after[a].position,sen[after[a].direct + 1]);
}
printf("\n");
}
}