Time Limit: 3000MS | Memory Limit: 65536KB | 64bit IO Format: %lld & %llu |
Description
Not so long time ago people used to believe that they live on 2-D world and if they will travel long enough in one direction, they will fall down over the edge. Even when it was proved that the Earth is rounded some of them were still afraid to travel to the southern hemisphere.
Try to imagine one 1-D (linear) world. On such world there are only two possible directions (left and right). All inhabitants of such world were created exactly at the same time and suddenly all of them start to move (all with same constant velocity) in one or the other direction. If two inhabitants encounter each other, they politely exchange greetings and then they turn around and start to move in an opposite direction. When an inhabitant reaches the end of the world he falls away and disappears.
Your task is to determine, for a given scenario of creation, which inhabitant and when (counting from the moment of creation) will be the last one to fall away. You can assume that the time required to exchange greetings and turn around is 0.
Input
N
LV
DIR POS NAME
...
The first line defines the number of inhabitants (N<32000). Data set starting with value N=0 represents the end of the input file. The second line contains length of the world L(float) and velocity of inhabitants V(float). Both values are always positive. In next N lines the data about inhabitants are given in an order of increasing POS (positive direction):
DIR – initial direction ('p' or 'P' for positive and 'n' or 'N' for negative)
POS – position in the time of creation (0<=POS<=L)
NAME – name of inhabitant (string up to 250 characters)
Input values within one line are separated with at least one space and there will be no empty lines in input. You may assume that input is always correct and that each data set has only one unique solution.
Output
Sample Input
1 13.5 2 p 3.5 Smarty 4 10 1 p 1 Helga n 3 Joanna p 5 Venus n 7 Clever 0
Sample Output
5.00 Smarty 9.00 Venus
题目大意
给定一条直线,长度为L 表示区间[0, L]。在直线上开始放置N个人,每个人有一个初始位置pos(用到直线上端点0的距离表示)和初始方向dir('p' 或 'P' 表示向端点L行走, 'n'或'N'表示向端点0行走),然后所有的人都开始沿着自己的方向用相同的速度v行走,若走到端点0或端点L,则此人掉下去;若两个方向相反的人碰到一起,则分别掉头,继续行走(速度不变)。
求出最后掉下去的人,和掉下去的时间。
题目分析
弹性碰撞的问题,如果只是求最后掉下的时间,由于碰撞只是交换方向,速度不变,因此可以视为两个人只是“擦肩而过”,各自的速度方向均未发生变化,这样转换之后的整体的效果和之前的整体的效果是一样的。那么,求最后掉下的时间就可以直接求每个人走到各自方向的端点所需要的时间,然后求最大值即可。此时,记录获得最大值的人为A。
然而此题还需要求最后掉下去的人是谁,那么最后掉下去的人肯定就是和A碰撞过的人一直不停的碰撞的最后一个人。即,若A和B碰撞,之后B又和C碰撞,之后C又和.... 的最后一个人。
可以按照初始位置对N个人进行排序,找出从A到A方向的端点之间和A方向相反的人的个数count,可以画图得知,从A开始,沿着A的方向的第count个人,就是最后和A碰撞之后的人碰撞的那个人,输出即可。
这题就是蚂蚁碰撞模板,难得是求第几个人,,根据碰撞的顺序找规律,,,
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 40000;
struct node
{
int dir, id;
double pos, t;
char name[300];
}p[N];
int cmp(node a,node b)
{
return a.pos<b.pos;
}
int main()
{
int n;
while(scanf("%d", &n),n!=0)
{
double l, v;
scanf("%lf %lf", &l, &v);
int id;
double tmp=0;
for(int i=0;i<n;i++)
{
char s[10];
scanf("%s %lf %s",s, &p[i].pos, p[i].name);
if(s[0]=='p'||s[0]=='P')
{
p[i].dir=1;
p[i].t=(l-p[i].pos)/v;
}
else
{
p[i].dir=0;
p[i].t=(p[i].pos)/v;
}
}
sort(p,p+n,cmp);
for(int i=0;i<n;i++)
{
if(p[i].t>tmp)
{
id=i;
tmp=p[i].t;
}
}
if(p[id].dir==0)
{
int cnt=0;
for(int i=id;i>=0;i--)
{
if(p[i].dir==1)
{
cnt++;
}
}
printf("%13.2lf %s\n",int(p[id].t*100)/100.0,p[id-cnt].name);
}
else
{
int cnt=0;
for(int i=id+1;i<n;i++)
{
if(p[i].dir==0)
{
cnt++;
}
}
printf("%13.2lf %s\n",int(p[id].t*100)/100.0,p[id+cnt].name);
}
}
return 0;
}