1. 程式人生 > >2013-BIT程式設計 5.傳送帶 -- 排序

2013-BIT程式設計 5.傳送帶 -- 排序

小明的飛機快要趕不上了!
幸好大廳的路上有一些傳送帶。每個傳送帶都有一定的速度,傳送帶之間沒有重疊。
小明自己行走的速度為w,如果傳送帶的速度為v的話,在傳送帶上走的速度就是w+v。
但是小明還是很著急,所以他決定跑一段時間t。他跑的速度是r,那麼如果傳送帶的速度為v的話,在傳送帶上跑的速度就是r+v。
對於時間t,他不一定要連續跑,可以走走再跑。也不一定非要跑夠t。
問小明至少需要多少時間才能到達終點。

輸入第一行為用例數T,1<=T<=40。
每一組用例的第一行包含五個整數:
X:為大廳的長度,小明起始位於0,終點是X,1<=X<=1000000
W:為走路的速度
R:為跑步的速度,1<=W<R<=100
t:最多能跑t秒,1<=t<=1000000
n:傳送帶的個數
接下來的n行,表示n個傳送帶的詳細資訊。每行包含三個整數:Bi,Ei,Vi,分別表示傳送帶的起始位置、終止位置和速度,0<=Bi<Ei<=X,1<=vi<=100
輸出包含一個數字,表示至少需要多少時間。輸出四捨五入到6位小數。

輸入:
1.3↵
2.10 1 4 2 2↵
3.0 1 1↵
4.9 10 1↵
5.10 1 4 1000 2↵
6.0 1 1↵
7.9 10 6↵
8.20 1 3 20 5↵
9.0 4 5↵
10.4 8 4↵
11.8 12 3↵
12.12 16 2↵
13.16 20 1↵
 輸出:
1.3.000000↵
2.2.300000↵
3.3.53


分析:將地面看做是速度為0的傳送帶,最佳策略是 從速度最小的傳送帶開始跑,直到跑的時間用完,之後再走。計算時間即可。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 1000005
struct csd{
	double s;
	double v;
}dd[MAX];
int cmp(const void *a,const void *b)
{
	struct csd *x = (struct csd*)a;
	struct csd *y = (struct csd*)b;
	return x->v > y->v;
}
int main()
{
	int T;
	double w,r,t,tmps,x;
	int n;
	int b,e;
	scanf("%d",&T);
	while (T--)
	{
		tmps = 0.0;
		scanf("%lf%lf%lf%lf%d",&x,&w,&r,&t,&n);
		for (int i = 0; i < n; i++)		{
			scanf("%d%d%lf",&b,&e,&dd[i].v);
			dd[i].s = e-b;
			tmps += dd[i].s;
		}
		dd[n].s = x - tmps;dd[n].v = 0.0;
		qsort(dd,n+1,sizeof(dd[0]),cmp);
		double ans = 0.0;
		double tt = t,ts = 0;
		for (int i = 0; i <= n; i++)//在傳送帶上的過程
		{
			if(tt == 0.0)			
				ans += (dd[i].s)/(dd[i].v+w);			
			else if(tt*(dd[i].v+r) < (dd[i].s))//跑不全傳送帶
			{
				ans += tt;
				ts = dd[i].s-tt*(dd[i].v+r);//傳送帶上剩下的距離
				tt -= tt;				
				ans += ts/(dd[i].v+w);//在傳送帶上 走 的時間
			}else{//剩餘的時間還夠跑全這一個傳送帶
				ans += (dd[i].s)/(dd[i].v+r);
				tt -= (dd[i].s)/(dd[i].v+r);
			}
		}
		printf("%.6lf\n",ans);
	}
	return 0;
}