poj_2674 弹性碰撞

题目大意

给定一条直线,长度为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碰撞之后的人碰撞的那个人,输出即可。

实现(c++)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<cmath>
#include<iostream>
using namespace std;
#define MAX_N 32005
#define max(a, b) a >b?a:b
double gStartPos[MAX_N];
int gPre[MAX_N];
struct Person{
	int dir;
	double start_pos;
	char name[255];
};
Person gPerson[MAX_N];
bool Cmp(const Person& p1, const Person& p2){
	return p1.start_pos < p2.start_pos;
}

int main(){
	int n;
	double l, v;
	while (cin >> n  && n){
		cin >> l >> v;
		char dir;
		double max_t = 0;
		int max_id;
		for (int i = 0; i < n; i++){
			cin >> dir >> gPerson[i].start_pos >> gPerson[i].name;
			gPerson[i].dir = ((dir == ‘p‘ || dir == ‘P‘)? 0 : 1);
		}
		sort(gPerson, gPerson + n, Cmp);
		for (int i = 0; i < n; i ++){
			if (gPerson[i].dir == 1){
				if (max_t < gPerson[i].start_pos / v){
					max_t = gPerson[i].start_pos / v;
					max_id = i;
				}
			}
			else{
				if (max_t < (l - gPerson[i].start_pos) / v){
					max_t = (l - gPerson[i].start_pos) / v;
					max_id = i;
				}
			}
		}
		int count = 0;
		int id = 0;
		if (gPerson[max_id].dir == 0){
			for (int i = max_id + 1; i < n; i++){
				if (gPerson[i].dir == 1){
					count++;
				}
			}
			id = max_id + count;
		}
		else{
			for (int i = 0; i < max_id; i++){
				if (gPerson[i].dir == 0){
					count++;
				}
			}
			id = max_id - count;
		}
		//!!!! 截断小数,取后两位,而不是四舍五入!
		printf("%13.2lf %s\n", int(max_t*100)/100.0, gPerson[id].name);
	}
	return 0;
}
时间: 2024-09-30 15:14:13

poj_2674 弹性碰撞的相关文章

完美世界笔试题---小球弹性碰撞

题目描述: 时间限制:c/c++语言1000MS: 其它语言3000MS 内存限制:c/c++语言65536KB:其他语言589824KB 如下图一个类似手机屏幕的矩形区域,宽度为w,高度为h,一个小球(视为质点,忽略其体积大小)初始位于底边距离左侧x的位置,向右上角45度发射.当小球碰到边界时,按完全弹性碰撞理想反弹,如果小球恰好碰到角落,则反向返回.如此无限循环. 请编写程序,输出前n次小球回到底边时的横坐标(首次发射时的不算). 输入: 每个输入是一行依次表示为w,h,x,n的4个正整数,

poj 3684 Physics Experiment 弹性碰撞

Physics Experiment Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1489   Accepted: 509   Special Judge Description Simon is doing a physics experiment with N identical balls with the same radius of R centimeters. Before the experiment,

POJ 2674-Linear world(弹性碰撞)

Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 3119Accepted: 696 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

Greedy:Physics Experiment(弹性碰撞模型)(POJ 3848)

物理实验 题目大意:有一个与地面垂直的管子,管口与地面相距H,管子里面有很多弹性球,从t=0时,第一个球从管口求开始下落,然后每1s就会又有球从球当前位置开始下落,球碰到地面原速返回,球与球之间相碰会发生完全弹性碰撞(各自方向改变,速率变为相碰时另一个球的速率)问最后所有球的位置? 这一题又是一道弹性碰撞模型的题目,和Liner World有点像,但是这一题不要求输出球的名字,而是要你求得各个球的高度 这道题我们只用明白一个道理就很方便了: 首先我们来看一个球的情况: 一个球从H的高度下落,碰到

python开发_tkinter_小球完全弹性碰撞游戏

python开发_tkinter_小球完全弹性碰撞游戏 完成这个小球的完全弹性碰撞游戏灵感来自于: 下面是我花了一周下班时间所编写的一个小球完全弹性碰撞游戏: 游戏初始化状态: 最下面的游标和修改小球的移动速度 =================================================== 源码部分: =================================================== 1 #python tkinter 2 #python versio

pygame系列_小球完全弹性碰撞游戏

之前做了一个基于python的tkinter的小球完全碰撞游戏: 今天利用业余时间,写了一个功能要强大一些的小球完全碰撞游戏: 游戏名称: 小球完全弹性碰撞游戏规则: 1.游戏初始化的时候,有5个不同颜色的小球进行碰撞 2.玩家可以通过在窗口中单击鼠标左键进行增加小球个数 3.玩家可以通过在窗口中单击鼠标右键进行删减小球个数 4.玩家可以通过键盘的方向键:上,右键进行对小球加速 5.玩家可以通过键盘的方向键:下,左键进行对小球减速 6.玩家可以按键盘:f键实现全屏显示 7.玩家可以按键盘:Esc

C++多小球非对心弹性碰撞(HGE引擎)

程序是一个月前完成的,之前一直没正儿八经的来整理下这个程序,感觉比较简单,不过即使简单的东西也要跟大家分享下. 源码下载:http://download.csdn.net/detail/y85171642/7209727 开篇 开始上代码之前我先说下我为啥写的这个程序,大三的时候学习C#接触过GDI+而发现原来做图形界面的程序也可以这么简单.之后便开始用GDI+做起动画.游戏等,其中便有一个模拟多小球碰撞的,在CSDN上有分享过( http://pan.baidu.com/s/1qWjTkmS 

[CF 848B] Rooter&#39;s Song 二维弹性碰撞

题意 在平面直角坐标系中, 有一个以 (0, 0) 为左下角, (w, h) 为右上角的矩形. 有 n 个人, 它们一开始站在 x 轴或者 y 轴上, 第 i 个人的坐标为 $p_i$ , 准备跳舞. 对于第 i 个人, 它最开始会在原地站立 t 秒, 然后朝着矩形的对面跳舞, 每 1s 跳 1 个单位长度. 如果两个人相遇了, 那么它们会相互走另一个人的路线. 人们会一直走着, 直到它们到达了矩形的某个边界. 问每个人最后会走到的坐标. 分析 二维弹性碰撞. 大致地思路是先回顾一维弹性碰撞,

富有弹性碰撞缓冲的竖向JS导航菜单

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-