题目大意是,在一个一维的世界里有N个居民在一条直线上的不同位置,他们以恒定的速度大小,速度方向可能不同进行运动,相遇后会返回,问给定线段的长度l,速度v,求最后一个走出这个范围的居民是谁,用时多少。
举个例子,我们可以现象一下几个质量相同刚体(忽略他们的半径)在同一直线上运动,速度方向可能不同,所以会发生弹性碰撞,假设没有任何能量损耗的话,碰撞后是彼此交换速度后返回的,如果求在t时刻,这些球的位置该如何求。因为相遇后彼此交换了速度后返回,所以从表面上看起来碰撞后各个球还是继续沿着原来的方向运动,所以可以求出t时刻这些刚体的分散在的位置,但是不能对上号,因为实际上发生碰撞后会返回的,但是注意一个细节就是不管这些球如何碰撞多少次,他们之间的相对顺序是不会变化的,所以对求出来的位置进行排个序就可以对上号了
分析出这个思想不难,但很多人wa在细节上。最后的结果是截取小数而不是四舍五入,这点需要注意。
下面附上我的ac代码
#include <iostream>
#include<math.h>
#include<algorithm>
#include <iomanip>
#include<stdio.h>
#define N 33000
using namespace std;
typedef struct
{
char direct;
double pos;
string name;
}People;
bool cmp(const People &a,const People &b)
{
return a.pos<b.pos;
}
People p[N];
int n;
int main()
{
while(cin>>n&&n)
{
int z=0,i=0;
double s=0.0,s1=0.0;
double L,v;
cin>>L>>v;
int k=0,num=0,d=0;
for(i=0;i<n;i++)
{
char ch=getchar();
scanf("%c%lf",&p[i].direct,&p[i].pos);
cin>>p[i].name;
}
//cin>>p[i].direct>>p[i].pos>>p[i].name;
sort(p,p+n,cmp);
for(i=0;i<n;i++)
{
if(p[i].direct=='p'||p[i].direct=='P')
s1=L-p[i].pos;
else
s1=p[i].pos;
if(s<s1)
{
s=s1;
k=i;
}
}
if(p[k].direct=='p'||p[k].direct=='P')
{
for(i=k+1;i<n;i++)
{
if(p[i].direct=='n'||p[i].direct=='N')
num++;
}
d=k+num;
}
else
{
for(i=0;i<k;i++)
{
if(p[i].direct=='p'||p[i].direct=='P')
num++;
}
d=k-num;
}
cout << setw(13) << fixed << setprecision(2) << (int)(s/v * 100) / 100.0 << ' ' << p[d].name <<endl;
}
return 0;
}