题意:
有个人租车,去看电影, 车有价格,和油箱容量,途中有K个加油站,加油不花钱。问这个人最少花多少钱,可以在t分钟之内(包括T)赶到
思路:
二分枚举油箱容量,找到一个最小的容量的油箱,可以到达T时间,然后再回去扫一遍所有gas>=这个容量中车的最小价格就是答案
感想:
自己想的时候感觉很像上一场的C题 魔法药水,如果有印象的可以去翻下, 结果自己智障了,没写二分。一发AC以为可以了。结果终判TLE了。真是智障哇!
每次做到CF的C题总会感觉用到二分来缩小时间,然而二分的重点应该在找到我们需要的变量才是关键,比如这题我们如果找其他的变量 (车,加油站)根本无法进行有效
的二分,所以油箱的确是个很好的选择。自己TLE的不冤,还是太菜啊。下次C题好好想想
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define maxn 200005
#define inf 2000000005
typedef long long ll;
ll n,k,s,t;
struct node
{
ll val,gas;
} car[maxn];;
ll dis[maxn];
ll carmp(node a,node b)
{
return a.val<b.val;
}
ll cmp(ll a,ll b)
{
return a>b;
}
int judge(ll x)
{
ll len,time=0;
for(int i=1;i<=k+1;i++)
{
len=dis[i]-dis[i-1];
if(len>x)
return 0;
time+=(2*len)-min(len,x-len);
if(time>t)
return 0;
}
return 1;
}
int main()
{
cin>>n>>k>>s>>t;
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&car[i].val,&car[i].gas);
}
for(int i=1;i<=k;i++)
{
scanf("%lld",&dis[i]);
}
if(t<s)
{
printf("-1\n");
return 0;
}
dis[k+1]=s;
dis[0]=0;
sort(dis,dis+2+k);
ll l=0,r=2e+9;
while(l<r)
{
ll mid=(l+r)/2;
if(judge(mid))
{
r=mid;
}
else
{
l=mid+1;
}
}
// cout<<r<<endl;
ll minn=inf;
for(int i=1;i<=n;i++)
{
if(car[i].gas>=r)
minn=min(minn,car[i].val);
}
if(minn!=inf)
cout<<minn<<endl;
else
cout<<-1<<endl;
return 0;
}
/*
2 1 1000000000 2000000000
111 999999998
101 999999998
1
*/