告诉你有一个长为L(L<=10000)的木杆,上面有N(N<=1000)个蚂蚁,他们一开始的朝向随机,他们会以一定的速度一直向当前方向走,直到两只蚂蚁相遇,他们会立即掉头(即往相反方向走),计算T秒后蚂蚁的位置
输入的第一行为数组个数,
每组数组第一行为三个正整数,L,T,n,分别表示长度,时间,蚂蚁个数。
L 表示向左,R表示向右
输出格式为n行,输出每个蚂蚁的位置和朝向,如果T秒内已经掉下,输出fell off。
样例输入:
1
10 1 4
1 R
5 R
3 L
10 R
输出:
Case:#1
2 turing
6 R
2 turing
fell off
分析:首先要知道一个原则,蚂蚁的相对位置不变,比如一开始,在1 4 8 三个位置有甲乙丙三个蚂蚁,无论每个蚂蚁的位置如何,朝向如何,在不掉下杆的前提下,无论他们怎么对头,他们的相对位置都是不变的,甲一定在乙前面,乙一定在丙前面,只是可能距离发生了改变,位置发生了改变,另外一个原则是,假设在某时刻两个蚂蚁相对而行,而且运行到某一点,这时候他们会掉头运行,但是其结果,其实和对穿而过是一样的,所以我们可以按照这个原则来很快确定其最后状态,比如一开始为1 R 3L,5R,经过两秒后,可以判断其最终态一定是3 R,1 L,7R,省略了复杂的分析过程,直接一步到位,只是,位置是3R的,未必是初始位置是1R的。
基于以上两个原则,我们写出如下代码
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int max=10000;
typedef struct a
{
int id;
int pos;
int status;
}ants;
ants before[max];
ants after[max];
int record[max];
const char information[][10]={{"L"},{"turning"},{"R"}};
//1 代表右转 -1代表左转 0代表正在转身
bool cmp(ants & a,ants & b)
{
return a.pos<b.pos;
}
bool cmp_id(ants & a,ants & b)
{
return a.id<b.id;
}
int main()
{
int time;
int L,T,n;
int i,j;
int len;
char c_status;
cin>>time;
while(time--)
{
i=0;
j=1;
cin>>L>>T>>n;
len=n;
while(len--)
{
before[i].id=i;
after[i].id=0;
cin>>before[i].pos;
cin>>c_status;
if(c_status=='L')
{
before[i].status=-1;
after[i].status=-1;
}
else if(c_status=='R')
{
before[i].status=1;
after[i].status=1;
}
after[i].pos=before[i].pos+before[i].status*T;
i++;
}
sort(before,before+n,cmp);
sort(after,after+n,cmp);
for(i=0;i<n;i++)
{
after[i].id=before[i].id;
}
sort(after,after+n,cmp_id);
for(i=0;i<n-1;i++)
{
if(after[i].pos==after[i+1].pos)
{
after[i].status=after[i+1].status=0;
}
}
cout<<"Case #"<<j<<endl;
for(i=0;i<n;i++)
{
if(after[i].pos<0||after[i].pos>10)
cout<<"Fell off"<<endl;
cout<<after[i].pos<<" "<<information[after[i].status+1]<<endl;
}
j++;
}
return 0;
}