poj 1852&3684 题解

poj 1852 3684

这两题思路相似就放在一起.

1852

题意

一块长为L长度单位的板子(从0开始)上有很多只蚂蚁,给出它们的位置,它们的方向不确定,速度为每秒一长度单位,当两只蚂蚁相遇的时候,它们会反向而行,问所有蚂蚁到达终点(到0或者到L)所需要的最短时间和最长时间。

解析

一开始拿到这题觉得还是有点难度的,但一想通就发现这是个大水题。我们可以假设两只蚂蚁它们相向而行,并且它们中间没有别的蚂蚁,此时它们距离为k,经过时间t后它们相遇,此时它们反向,又经过时间t它们再次之间距离还是k。但如果我们假设它们相遇不反向,那么它们的情况也是一样的。所以这些所谓的反向都是在迷惑你,事实上根本不需要反向这种操作,所以这题就变得非常水了。

代码

#include<cstdio>
#include<algorithm>
using namespace std;
int T,n,s,k;
int main(){
	scanf("%d",&T);
	while(T--){
		int minn=0;
		int maxn=0;
		scanf("%d %d",&s,&n);
		for(int i=1;i<=n;++i){
			scanf("%d",&k);
			minn=max(minn,min(k,s-k));
			maxn=max(maxn,max(k,s-k));
		}
		printf("%d %d
",minn,maxn);
	}
	return 0;
}

3684

题意

将N个半径为R的球放入一个圆桶(圆桶口径刚好放入一个球),将圆桶竖直放着,最下端距离地面H高度,让球每隔一秒自由下落,求T时刻各个球距离地面的高度。(弹性碰撞没有能量损失)

解析

跟前面的题目相同,由于质量相同,碰撞又没有能量损失,由动量守恒可知它们只是速度反向,所有的球都一样可以忽视它们的碰撞,视为互相穿过继续运动。这样就可以分别单独求出每个球T时刻的高度后排序就是答案了。

代码

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double g=10.0;
int N,H,R,T,C;
double y[110];
double cal(double T){
	if(T<0) return H;
	double t=sqrt(2*(double)H/g);
	int k=T/t;
	if(k&1){//判断向上还是向下,奇数向上,偶数向下
		double d=k*t+t-T;
		return H-(d*d*g/2.0);
	}else{
		double d=T-k*t;
		return H-(d*d*g/2.0);	
	}
}
int main(){
	scanf("%d",&C);
	while(C--){
		scanf("%d %d %d %d",&N,&H,&R,&T);
		for(int i=0;i<N;++i){
			y[i]=cal((double)T-i);
		}
		sort(y,y+N);
		for(int i=0;i<N;++i){
			printf("%.2f%c",y[i]+2*R*i/100.0,i+1==N ? '
':' ');//cm->m
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/donkey2603089141/p/11680020.html