得分显示(浮点数二分)
链接:https://ac.nowcoder.com/acm/contest/72980/C
来源:牛客网
小菜鸡今天在打某款 ingteresting 的游戏。每当他通关游戏的某一关卡,该关卡的累计得分值就会增加 \(\mathrm{x}\)。由于\(\mathrm{x}\) 是一个正实数,因此存在累计得分值不为整数的情况。但是该游戏的累计得分值只能显示整数部分,于是小菜鸡突发奇想,就有了下面的题。
已知小菜鸡共通关该关卡\(\mathrm{n}\)次,依次给出小菜鸡每次通过关卡后,该关卡显示的累计得分值(即累计得分值的整数部分),请求出单次通过该关卡所增加的得分值\(\mathrm{x}\)最大为多少?
输入描述:
第一行给出一个整数\(\mathrm{n}(1\le \mathrm{n} \le 10^{6})\)
下一行共\(\mathrm{n}\)个整数,第\(\mathrm{i}\)个整数 $ \mathrm{a_i}$ \((0\le \mathrm{a_i} \le 10^{9})\)表示小菜鸡通过该关卡第\(\mathrm{i}\)次时所显示的累计得分值。
特殊地,可以认为在刚开始时,关卡的累计得分值为 0 。
输入数据保证存在至少一个合法解。
输出描述:
输出一个实数,表示 \(\mathrm{x}\) 可取到的最大值。你需要保证输出结果与答案绝对误差不超过\(10^{-4}\)。
示例1
输入
5
0 0 0 0 0
输出
0.2000000000
说明
样例一中,每次通关所显示的总分值都是 0 ,说明总得分值其真实值所处范围为 [0,1)。因此,单次通关可能增加的得分值最大应为 0.1999999.....,保留 10位小数后应为 0.2000000000
典型的二分:
#include<algorithm>
#include<map>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int mod=20011021;
const int maxn=1e6+100;
const int INF=0x3f3f3f3f;
int a[maxn];
int n;
int judge(double x){
double sum=0;
for(int i=1;i<=n;i++){
sum+=x;
if((ll)sum>a[i]) return 0;
}
return 1;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
double l = 0,r = 2e9;
double e=1e-6;
while(r-l>e){
double mid=(l+r)/2;
if(judge(mid)){
l=mid;
}else{
r=mid;
}
}
cout<<fixed<<setprecision(15)<<l<<endl;
}