https://ac.nowcoder.com/acm/contest/3005/G
题目描述
作为“音乐鉴赏”课的任课老师,你的课程作为刷学分好课一直受到广泛欢迎。但这一学期,学校制定了新的标准,你的课的优秀率(分数超过90分的人数)被限制在10%以下!
为了应对这个调整,你要求所有的同学都写了一篇论文,并使用随机算法打出了0-90之间的分数,分数可能不是整数。这里的随机是指,对于在[0,90]这个闭区间上的任何一对等长的区间,分数出现在其中的概率均是相同的。在期末的分数占比为百分之多少的时候,你的课程优秀率期望恰好在10%?保证所有同学的平时成绩都高于90分。
思路
二分期末分数所占的比例,对于每一种比例x,判断其是否可行。判断可行的方法是,求优秀人数的期望。根据x可以求出来平时成绩所占的比例,如果平时成绩×(1.0 - x)大于等于90,说明这个人一定是优,sum = sum + 1,如果不满足这个条件,就求一下离90差多少分,根据差值和占比x求出原来期末成绩,只要成绩比这个大或者等于,并且在90之间都可行,所以成绩的区间就是(90 - s) 根据这个区间在0到90所占的比例就求出来了这个人优秀的概率p,sum += p,最后sum的和就是优秀人数的期望值,判断期望值和n / 10的大小,然后改变二分上下限
/*************************************************************************
> File Name: G.cpp
> Author: amoscykl
> Mail: [email protected]
> Created Time: 2020年02月12日 星期三 23时09分03秒
************************************************************************/
#include<bits/stdc++.h>
using namespace std;
const int N = 101000;
double a[N];
int n;
#define eps 1e-8
bool check(double x){
double sum = 0;
double temp = 1.0 - x;
for (int i = 1; i <= n; i++){
if (a[i] * temp >= 90)sum++;
else{
double need = 90 - a[i] * temp;
need /= x;
need = (90 - need) / 90.0;
sum += need;
}
}
return sum <= n / 10;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)scanf("%lf", &a[i]);
double l = 0.0;
double r = 1.0;
double res = -1.0;
while (r - l > eps){
double mid = (l + r) / 2;
if (check(mid)){
res = mid;
r = mid;
}
else l = mid;
}
printf("%.2lf%c", res * 100, '%');
return 0;
}