题意:
1.给你n辆车,k个加油站,s路程,t秒内到达
2.所有车都有两种mode:1km / min 和 1km / 2min,耗油量是 2/km 和 1/km
3.每辆车有价格和油罐容量,路过加油站汽油可瞬间满血。求最便宜的车。
思路:
1.写一个bool函数judge,用来判断车花费最少时间mint,如果mint<=t返回真。用加油站把路程分组,每组求出mint,累加起来。
2.每组路程dis有三种情况:
A.油罐容量feul<dis,说明用慢速都到大不了,return false;
B.油罐容量fuel>=2*dis,说明直接用高速到达即可,速度是1km/min,所以mint+=dis;
C. 油罐容量介于AB之间,尽可能用高速。设高速行驶x km,低速行驶y km。
则有x+y=dis,2x+y<=feul。
得出x<=fuel-dis,即x的最大值为fuel-dis。mint+=x+2*y。
3.用车中的最大油罐量maxfuel走一次judge,如果不行直接输出-1。否则二分(0,maxfuel)求出能准时到达的最小油罐容量。
4.最后扫一遍车,如果车的容量大于最小容量,则res=min(res,car[i].cost);
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
#include<iostream>
#include<algorithm>
#include<cstdio>
using
namespace
std;
const
int
maxn=200200;
struct
Car
{
int
cost, fuel;
}car[maxn];
int
gas[maxn];
bool
judge(
int
fuel,
int
k,
int
t)
{
/*
x+y=dis
2x+y<=fuel
so x<=fuel-dis
x represent the distance with high speed, y ...
*/
int
i,j;
int
mint=0;
for
(i=1;i<=k+1;i++)
{
int
dis=gas[i]-gas[i-1];
if
(fuel<dis)
return
false
;
else
if
(fuel>=2*dis)
mint+=dis;
else
{
int
x=fuel-dis;
int
y=dis-x;
mint+=x+2*y;
}
}
return
mint<=t;
}
int
main()
{
int
n,k,s,t,i,j;
scanf
(
"%d%d%d%d"
,&n,&k,&s,&t);
int
maxfuel=-1;
for
(i=1;i<=n;i++)
scanf
(
"%d%d"
,&car[i].cost,&car[i].fuel),
maxfuel=max(maxfuel,car[i].fuel);
for
(i=1;i<=k;i++)
scanf
(
"%d"
,&gas[i]);
sort(gas+1,gas+k+1);
gas[0]=0;
gas[k+1]=s;
if
(!judge(maxfuel,k,t))
{
printf
(
"-1\n"
);
return
0;
}
int
low,high;
low=0,high=maxfuel;
while
(low<high)
{
int
mid=low+high >> 1;
if
(judge(mid,k,t))
high=mid;
else
low=mid+1;
}
int
res=2e9+5;
for
(i=1;i<=n;i++)
if
(car[i].fuel>=low)
res=min(res,car[i].cost);
printf
(
"%d\n"
,res);
}
|