简介:
蚂蚁们在树枝上的运动
分析:
假如我们离远一点,看这些蚂蚁会是什么样呢
一群密密麻麻的小黑点在移动,由于黑点太小,而且移动速度都相等,
所以当蚂蚁因碰撞而掉头时,看上去和两个点对穿而过没有什么区别
换句话说,如果把蚂蚁看做没有区别的小黑点,那么只要独立计算每只蚂蚁在T时刻的位置即可
比如,有3只蚂蚁:(3,R),(4,L),(6,L)
则两秒之后三只蚂蚁分别为:(5,R),(2,L),(4,L)
现在我们已经得到答案了,但是还有一个problem
在实际问题中,两只蚂蚁是不会对穿的,
也就是说,蚂蚁1的初始位置是(3,R),一定有一只蚂蚁的最终位置是(5,R),但是不一定是蚂蚁1,
所以我们现在的问题是把坐标的蚂蚁对上号,弄清楚“谁是谁”
我们观察一下蚂蚁们行进的路线,
不会对穿是一个很重要的信息,也就是说,ta们只能在一个没有其他蚂蚁的区间内运动,是不会越过任何蚂蚁的
换句话说:
ta们的相对位置是不会变的
因此把所有目标位置从小到大排序,则从左到右的每个位置对应了初始状态下从左到右的每只蚂蚁
由于一开始给出的蚂蚁可能是无序的
所以我们还需要处理一下每只蚂蚁的排名
tip
在算出最终坐标之后,如果发现两个相邻蚂蚁的坐标相等,那么说明ta们正在转身
小于0大于L才视为掉下木棍
我就因为少输出了一行空行,就PE了
真的搞不懂外国佬为什么老是本末倒置
//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=10003;
int n,l,t;
struct Ant{
int id;
int p;
int d; //-1 left 0 turning 1 right
};
Ant before[N],after[N];
int wz[N];
int cmp(const Ant &a,const Ant &b)
{
return a.p<b.p;
}
int main()
{
int T;
scanf("%d",&T);
for (int cas=1;cas<=T;cas++)
{
scanf("%d%d%d",&l,&t,&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&before[i].p);
char ch[2];
scanf("%s",&ch);
if (ch[0]=='R') before[i].d=1;
else before[i].d=-1;
before[i].id=i;
}
sort(before+1,before+n+1,cmp);
for (int i=1;i<=n;i++)
{
after[i]=before[i];
if (after[i].d==1)
after[i].p+=t;
else after[i].p-=t;
wz[before[i].id]=i; //第i个输入的蚂蚁实际上排第wz[i]个
}
sort(after+1,after+1+n,cmp);
for (int i=1;i<n;i++)
if (after[i].p==after[i+1].p) after[i].d=after[i+1].d=0;
printf("Case #%d:\n",cas);
for (int i=1;i<=n;i++)
{
int r=wz[i];
if (after[r].p>l||after[r].p<0) printf("Fell off\n");
else
{
printf("%d ",after[r].p);
if (after[r].d==-1) printf("L\n");
else if (after[r].d==1) printf("R\n");
else printf("Turning\n");
}
}
puts("");
}
return 0;
}