刷题笔记:Luogu P3743
Solution
最多能将这些设备一起使用多久,显然答案满足单调性(如果\(x<y\)而不能使用\(x\)时间则一定不能使用\(y\)时间)
通俗一点,就是前边的时间不满足则后边一定不满足,也就是局部答案舍弃性,考虑二分时间
至于check怎么写呢?
和奶牛晒衣服有异曲同工之妙,若设二分出来的时间为\(t\),如果每台设备需要充电宝才能至少支持\(t\)秒,将需要充电宝支持的时间累计为\(sum\),最后判断\(sum\leq t\)即可
由于实数二分,我们不能直接按照题意模拟(不能使用枚举到\(t\)的做法,因为\(t\)是实数)
实数二分还需要控制一下精度,大概是这样的:
实数二分的时候:如果误差小于四位小数,eps就等于1e-6,如果误差小于五位小数,eps就等于1e-7,如果误差小于六位小数,eps就等于1e-8。就是比误差多两位就可以。
(eps指while(r-l>eps)
)
具体做法见代码吧 卡精度真的恶心人啊
CODE
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define INF 1e10
#define N 1000010
#define MINN 1e-6 //开大一点也没关系
using namespace std;
int n,p;
int a[N],b[N];
struct Node
{
double a,b;
}cpy[N];
void copy()
{
for(int i=1;i<=n;i++)
{
cpy[i].a = a[i];
cpy[i].b = b[i];
}
}
bool cmp(Node a,Node b)
{
return (a.b-a.a) < (b.b-b.a);
}
bool check(double x)
{
copy(); //闲的,显然没必要,但是懒得删了()
double power = 0;
for(int i=1;i<=n;i++)
{
if(cpy[i].a*x > cpy[i].b) power += cpy[i].a*x*1.0-cpy[i].b;
}
return power <= p*x;
}
int main()
{
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
double l = 0,r = INF;
while(r - l > MINN)
{
double mid = (l+r)/2;
if(check(mid)) l = mid;
else r = mid -MINN; //这里也需要注意一下精度
}
if(r == INF) printf("-1\n");
else printf("%.10lf\n",r);
return 0;
}
本文作者:SXqwq,转载请注明原文链接:https://www.cnblogs.com/SXqwq/p/17413500.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!