POJ - 2674 Linear world(弹性碰撞)

Linear world
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 3384 Accepted: 753

Description

The Disc, being flat, has no real horizon. Any adventurous sailors who get funny ideas from staring at eggs and oranges for too long and set out for the antipodes soon learned that the reason why distant ships sometimes looked as though they were disappearing over the edge of the world was that they were disappearing over the edge of the world. (Terry Pratchett -Colour of Magic) 
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

The input consists of multiple descriptions (data sets) of the creation moment. File structure is as follows: 

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

The output consists of one line per each input data set. The first value should be the time when the last inhabitant will fall of the linear world counting from the moment of creation. Value should be printed truncated to two decimal places in a field 13 characters wide. The second value should be the name of the inhabitant. Values should be separated with single space character.

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
题意:一条线上N只蚂蚁,每只蚂蚁速度固定,方向和坐标不同,碰头后掉头,求最后掉下去那只蚂蚁的时间和名字,其中时间前面要有13位,不足补空格。
此题要注意以下几点:
1.由于会发生碰撞并且掉头,所以蚂蚁的顺序是不会发生改变的,在中间的依旧在中间,在两边的依旧在两边
2.如果单纯用algorithm提供的sort函数会超时
3.如果直接用%13.2f对时间进行截取的话,浮点数会直接四舍五入,而这里却不能四舍五入,而是需要直接截取小数点后两位。
4.'p' 和 'P', 'n'和'N'都要检测,否则会WA

针对第二个,解决方案很简单:只要找到了最后那个离开的位置,然后我们遍历数组,找出有几个比它大就知道它在sort排序后处于哪个位置。
针对第三个,解决方案也简单:(int)(t * 100.) / 100.,就可以直接截取小数点后两位
这里用代码中的IO_Init()函数对C++输入输出可能会超,所以用C语言输入输出保险
/*头文件模板*/

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <typeinfo>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

#define pb push_back
#define mp make_pair
#define mem(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a))
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)

typedef long long LL;
typedef pair<int, int > PII;
typedef pair<int, string> PIS;
typedef unsigned long long uLL;

template<typename T>
void print (T* p, T* q, string Gap = " ", bool flag = false) {
	int d = p < q ? 1 : -1;
	while (p != q) {
		if (flag) cout << Gap[0] << *p << Gap[1];
		else cout << *p;
		p += d;
		if (p != q && !flag) cout << Gap;
	}
	cout << endl;
}

template<typename T>
void print (const T &a, string bes = "") {
	int len = bes.length();
	if (len >= 2) cout << bes[0] << a << bes[1] << endl;
	else cout << a << endl;
}

void IO_Init() {
	ios::sync_with_stdio (false);
}

LL LLabs (LL a) {
	return a > 0 ? a : -a;
}

const double PI = 3.1415926535898;
const double eps = 1e-10;
const int MAXM = 1e5 + 5;
const int MAXN = 32000 + 5;
const int INF = 0x3f3f3f3f;

/*头文件模板*/

int N;
double L, V;
char dir[2];
struct o {
	double pos;
	char c;
	bool operator < (const o &p) const {
		return pos < p.pos;
	}
} O[MAXN];
char S[MAXN][300];
int main() {
	//FIN;
	double pos;
	while(scanf("%d", &N), N) {
		scanf("%lf%lf", &L, &V);
		double maxL = 0;
		for(int i = 0; i < N; i ++) {
			scanf("%s%lf%s",dir, &pos, S[i]);
			O[i].c = dir[0];
			O[i].pos = pos;
			maxL = max(maxL, (O[i].c == 'p' || O[i].c == 'P') ? L - pos : pos);
		}

		double t = ceil(maxL / V);

		for(int i = 0; i < N; i ++) {
			if(O[i].c == 'p' || O[i].c == 'P') {
				O[i].pos += t * V;
			} else {
				O[i].pos -= t * V;
			}
		}
		double sl = INF, sd;
		for(int i = 0; i < N; i ++) {
			if(O[i].c == 'p' || O[i].c == 'P') {
				if(sl > abs(O[i].pos - L) - eps) {
					sl = abs(O[i].pos - L);
					sd = O[i].pos;
				}
			} else {
				if(sl > abs(O[i].pos) - eps) {
					sl = abs(O[i].pos);
					sd = O[i].pos;
				}
			}
		}
		int si = 0;
		for(int i = 0; i < N; i ++) {
			if(O[i].pos <= sd) {
				si ++;
			}
		}
		printf("%13.2f %s\n", (int)(maxL / V * 100.) / 100., S[si - 1]);
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值