题意:
给你n个装置,每个装置每分钟耗电p ,本身储存电c。
然后你有一个充电器,(随时充,转移不耗时,想怎么换着充都行)。
问你让所有装置都能保持工作的最大时间是多少。
以前模板都是用 1e-9 但是这里其实只需要到1e-5(虽然这能水过,但是这不是重点)。
。所以减少精度或者限定次数都可以。他们都是迭代 150到300次这样。。。注意这里要开longlong 重点。为什么要限定次数,因为浮点数的折半查找不安全, 它是用 r-l>0的这样一种模式,所以它会卡在某个点。实际上 递归次数到300这样精度已经很准确。这个时间复杂度 为 递归的次数n次数 也就是如果递归次数为1000 1e5 那么就是1e8
那就已经快超时了 达到了 500ms *4 就gg了 就是2s了
所以浮点数这样的超时的。。。一般加个(右边界-左边界) *精度就好
一般300肯定够了 也不会超时
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,a[101010],b[101001];
int p;
int check(double x)
{
double res=0;
for(int i=0;i<n;i++)
{
if(a[i]*1.0*x*10>(b[i]*1.0*10))
{
res+=(a[i]*1.0*x-(b[i]*1.0))/p;
}
}
if(res<=x){
return 1;
}
else return 0;
}
int main()
{
scanf("%d%d",&n,&p);
ll s=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i],&b[i]);
s+=a[i];
}
if(p>=s)
{
printf("-1\n");
return 0;
}
double l=0.0,r=1e18;
long long cnt=0;
while(r-l>1e-9)
{
cnt++;
double mid=(l+r)/2;
if(check(mid))
l=mid;
else
r=mid;
if(cnt>300) break;
}
printf("%.5lf\n",l );
}
或者控制精度即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,a[101010],b[101001];
int p;
int check(double x)
{
double res=0;
for(int i=0;i<n;i++)
{
if(a[i]*1.0*x*10>(b[i]*1.0*10))
{
res+=(a[i]*1.0*x-(b[i]*1.0))/p;
}
}
if(res<=x){
return 1;
}
else return 0;
}
int main()
{
scanf("%d%d",&n,&p);
ll s=0;
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i],&b[i]);
s+=a[i];
}
if(p>=s)
{
printf("-1\n");
return 0;
}
double l=0.0,r=1e18;
long long cnt=0;
while(r-l>=1e-4)
{
cnt++;
double mid=(l+r)/2;
if(check(mid))
l=mid;
else
r=mid;
}
printf("%.5lf\n",l );
}