题目链接:点击这里
这是一道很有意思的题。如果我们完全按照题意,最simple的想法就是把每个蚂蚁的位置用数组表示,然后每一时刻就更新位置。这种方法固然可行,但实现起来较为麻烦,而且我们并不需要蚂蚁的中间过程位置,浪费时间。
如果我们把例题中的每一秒的蚂蚁位置画出来,不难发现:
其蚂蚁的相对位置始终是不变的。也就是说,如果蚂蚁B最开始处于蚂蚁A或者蚂蚁C之间,最终的位置只有两种情况:1.fell off,2.仍然处于这两者之间。
从整体上讲,题意中的“掉头”和“穿墙而过”并没有任何区别,但对于单个蚂蚁来说是有变化的。因此,我们需要记录的是蚂蚁的相对顺序。例如,A的位置为(3,R),B的位置为(4,L),“穿墙”之后的位置分别为(4,R),(3,L),按照A、B的相对位置不变可知,A目前的位置为(3,L),B为(4,R),与题意相符。
代码如下:
#include <iostream>
#include <algorithm>
using namespace std;
int Length;
int Time;
int Number;
const int maxn = 10000 + 5;
struct ant
{
int status;//1 stands for right, -1 stands for left,0 stands for turning
int pos;
int id;
ant(int s,int p,int d)
{
status = s;
pos = p;
id = d;
}
ant(){};
bool operator < (const ant& a)const
{
return pos < a.pos;
}
} before[maxn],after[maxn];
const char dirName[][10] = {"L","Turning","R"};
int order[maxn];//输入的第i只蚂蚁是排序后的order[i]只蚂蚁
int main()
{
int n;
cin>>n;
for (int kase = 1;kase <= n;kase++)
{
cin>>Length>>Time>>Number;
for (int i = 0; i < Number; i++) //输入
{
int p;
char ch;
cin>>p>>ch;
if (ch == 'R')
{
before[i] = ant(1,p,i);
after[i] = ant(1,p+Time,0);//id not known yet
}
else//left
{
before[i] = ant(-1,p,i);
after[i] = ant(-1,p-Time,0);//id not known yet
}
}
sort(before,before+Number);
for (int i = 0; i < Number; i++)
{
order[before[i].id] = i;
}
sort(after,after+Number);
for (int i = 0; i < Number-1; i++)
{
if (after[i].pos == after[i+1].pos)
after[i].status = after[i+1].status = 0;//Turining status
}
cout<<"Case #"<<kase<<":"<<endl;
for (int i = 0 ;i < Number;i++)
{
int a = order[i];
if (after[a].pos < 0 || after[a].pos > Length)
cout<<"Fell off"<<endl;
else
{
cout<<after[a].pos<<" "<<dirName[after[a].status+1]<<endl;
}
}
cout<<endl;
}
return 0;
}