题目:
见https://www.luogu.com.cn/problem/P3743
思路:
本题可以采用实数域上二分答案进行求解,正常的实数域二分模板,那么如何判断呢.我是先在输入时变算好了该设备可以坚持的时间t,将二分的mid值与t进行比较,如果t>=mid,那么对于该设备来说他可以不充电就运行mid时间,如果t<mid,那么该设备就需要充电,计算出需要充电的时间t1,遍历一遍所有设备,求出t1总和,如果t1>mid那么mid值就无法满足,所以让r=mid,反之让l=mid…二分区间l=0,r=1e10,之前我让r=1e5有一个样例过不了,还有就是如果最后l=r=1e10那么说明可以这些设备无限使用,就输出-1.
还有题目精度是1e-4,所以我们设置二分精度为1e-6…
代码:
#include<iostream>
#include<cmath>
#define eps 1e-6
using namespace std;
const int N=1e5+10;
int n,p;
struct
{
int ai,bi;
double t;
}machines[N];
int check(double mid)
{
double cnt=0;
for(int i=1;i<=n;i++)
if(machines[i].t<mid)
{
double t=(machines[i].ai*mid-machines[i].bi)/p;
cnt+=t;
}
if(cnt>mid)
return 0;
return 1;
}
int main()
{
cin>>n>>p;
for(int i=1;i<=n;i++)
{
int ai,bi;
cin>>ai>>bi;
machines[i].ai=ai;
machines[i].bi=bi;
machines[i].t=bi*1.0/ai;
}
double l=0,r=1e10;
while(r-l>eps)
{
double mid=(l+r)/2;
if(check(mid)) l=mid;
else
r=mid;
}
if(abs(l-1e10)<=eps)
cout<<-1<<endl;
else
cout<<l<<endl;
return 0;
}