这题目需要思考一下,我们其实不必纠结于蚂蚁的掉头问题,因为我们直接可以把蚂蚁看做擦肩而过,而不必对它进行调头之类的修改操作。
因为即使把蚂蚁看做擦肩而过,它们每个蚂蚁每个时刻所处的位置其实和掉头的结果是一样的,你们可以想一下是不是。
虽然每只蚂蚁的真实位置改变了,但是它们的相对位置其实并没有改变,我们依旧看一下蚂蚁擦肩而过之后的序列,可以很明显地发现,这个序列它们之间的相对位置其实并没有发生什么变化,所以我们最重要的工作就是按输入顺序输出结果。
因为我们要按照蚂蚁的位置升序排序,排序之后蚂蚁的位置已经改变了。
此时我们开辟一个order数组,我们在读入的时候再给每只蚂蚁按照顺序赋予一个id值。
然后第一次排序之后,我们就按照排序后的蚂蚁序列的id,从1-n进行写入。这样的话我们来分析一下,这样写入,首先肯定不是一定先写1里面,再写2里面,然后到n这样子,它肯定是随机地写入,因为排序之后打乱了。
但是我们的i值是从1-n进行变化的,我们这个i值就是排序之后,每个id的位置,我们对id也按照1-n的顺序写入,也就是说我们是顺序按id值作为下标写入,虽然写入并不是在数组中连续的。
但是我们可以得到一个好处,就是我们读出的时候,按照1-n顺序读出,此时我们就可以直接找到对应的第一次排序后的位置。
因为我们已经相当于是把它按照顺序写入的,所以order的下表就变成了id值,我们不一定有序写入,但是我们写完之后,它一定是按照升序存的。
这点还是请读者自行手演,比较清晰。这样子的话,我们就可以通过id值找到对应的第一次排序的位置,也可以通过相对位置不变进行输出。
另外读入的时候,要在第一个格式控制符后面加上空格,来读入输入中第一个数字之后除空格的第一个非空字符。
以下代码:
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=10000+5;
int L,T,n;
int order[maxn];
struct Ant {
int id;
int p;
int d;
bool operator < (const Ant &a)const {
return p<a.p;
}
}before[maxn],after[maxn];
const char dirName[][10]={"L","Turning","R"};
int main()
{
int N,cnt=1;
scanf("%d",&N);
while (N--) {
scanf("%d%d%d",&L,&T,&n);
for (int i=0;i<n;i++) {
int p,d;
char c;
scanf("%d %c",&p,&c);
d=(c=='L'?-1:1);
before[i]=(Ant){i,p,d};
after[i]=(Ant){0,p+d*T,d};
}
/*for (int i=0;i<n;i++) {
printf("%d %d %d
",ant[i].p,ant[i].d,ant[i].id);
}*/
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].p==after[i+1].p) {
after[i].d=after[i+1].d=0;
}
}
printf("Case #%d:
",cnt++);
for (int i=0;i<n;i++) {
int a=order[i];
if (after[a].p<0||after[a].p>L)
printf("Fell off
");
else
printf("%d %s
",after[a].p,dirName[after[a].d+1]);
}
printf("
");
}
return 0;
}