P13374 [GCJ 2011 #2] Airport Walkways

题目描述

你现在在机场,站在 000 点。通往登机口的走廊长度为 XXX 米,你的飞机即将起飞。走廊上有若干条自动步道,每条步道的速度为 wiw_iwi。当你在步道上行走或奔跑时,你的速度为(你的速度 +++ wiw_iwi)。步道不会移动它们的位置,只是让你移动得更快。步道之间不会重叠:在走廊的任意一点,至多只有一条步道,但一条步道可以在另一条步道结束的地方开始。

你的正常步行速度为 SSS。你担心可能赶不上飞机,因此你可以选择奔跑一段时间——你最多可以以速度 RRR 奔跑 ttt 秒。你不需要连续奔跑 ttt 秒:你可以将这 ttt 秒分成任意多个时间段,甚至可以不用完全部时间。

请问,在你合理安排步行和奔跑的情况下,最短需要多少时间才能到达登机口 XXX 点?

输入格式

输入的第一行是测试用例数 TTT。接下来有 TTT 组测试数据。每组测试数据的第一行为五个整数:XXX(走廊长度,单位为米)、SSS(步行速度,单位为米/秒)、RRR(奔跑速度,单位为米/秒)、ttt(最大奔跑时间,单位为秒)、NNN(步道数量)。

接下来的 NNN 行,每行包含三个整数:BiB_iBiEiE_iEiwiw_iwi,分别表示第 iii 条步道的起点、终点(距离起点的米数)以及步道的速度(单位为米/秒)。

输出格式

对于每组测试数据,输出一行,格式为 “Case #xxx: yyy”,其中 xxx 是测试编号(从 111 开始),yyy 是你到达 XXX 点所需的最短时间(单位为秒)。当且仅当你的答案的相对或绝对误差不超过 10−610^{-6}106 时,才会被判为正确。

输入输出样例 #1

输入 #1

3
10 1 4 1 2
4 6 1
6 9 2
12 1 2 4 1
6 12 1
20 1 3 20 5
0 4 5
4 8 4
8 12 3
12 16 2
16 20 1

输出 #1

Case #1: 4.000000
Case #2: 5.500000
Case #3: 3.538095238

说明/提示

样例解释

在第一个样例中,最优的做法是立即开始奔跑,并奔跑 1 秒。

数据范围

  • 1≤T≤401 \leq T \leq 401T40
  • 1≤S<R≤1001 \leq S < R \leq 1001S<R100
  • 1≤wi≤1001 \leq w_i \leq 1001wi100
  • 0≤Bi<Ei≤X0 \leq B_i < E_i \leq X0Bi<EiX
  • Ei≤Bi+1E_i \leq B_{i+1}EiBi+1

小数据集(8 分,测试集 1 - 可见)

  • 1≤t≤1001 \leq t \leq 1001t100
  • 1≤X≤1001 \leq X \leq 1001X100
  • 1≤N≤201 \leq N \leq 201N20
  • 时间限制:3 秒。

大数据集(10 分,测试集 2 - 隐藏)

  • 1≤t≤1061 \leq t \leq 10^61t106
  • 1≤X≤1061 \leq X \leq 10^61X106
  • 1≤N≤10001 \leq N \leq 10001N1000
  • 时间限制:6 秒。

由 ChatGPT 4.1 翻译

C++实现

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1005;
struct line{ //存步道的结构体
	double lon,v;
}l[N];
int T,n;
double x,s,r,t,b,e,w;
double suml,sumt,vrun,lesst,uset;
bool cmp(line a,line b){
	return a.v<b.v;
}
signed main(){
	scanf("%lld",&T);
	for(int step=1;step<=T;step++){
		scanf("%lf%lf%lf%lf%lld",&x,&s,&r,&t,&n);
		suml=0,sumt=0,lesst=0;
		for(int i=1;i<=n;i++){
			scanf("%lf%lf%lf",&b,&e,&w);
			l[i].lon=e-b;
			l[i].v=s+w;
			suml+=l[i].lon;
		}
		if(x>suml){
			l[n+1].lon=x-suml;
			l[n+1].v=s;
			n++;
		}
		for(int i=1;i<=n;i++) sumt+=l[i].lon/l[i].v;
		sort(l+1,l+1+n,cmp);
		for(int i=1;i<=n;i++){
			if(t<=0) break;
			vrun=l[i].v-s+r;
			uset=min(t,l[i].lon/vrun);
			lesst+=uset*(r-s)/l[i].v;
			t-=uset;
		}
		printf("Case #%lld: %lf\n",step,sumt-lesst);
	}
	return 0;
}


在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐