poj2976 Dropping tests

Dropping tests

 POJ - 2976 

题目大意:

在一场测试中有N项,每一项都有bi个题目,答对ai个。总的答对率就是(a1+a2+....+an-1)/(b1+b2+....+bn-1),现在可以让你从这N项测验中抽出K门不计入总的答题中,问最高答对率会是多少? 

二分答案:

二分搜索答对率,每得到一个值x,将其乘以bi,将yi=ai-bi*x,再将yi从大到小排序,看前n-k个yi的和是否大于等于0,是则表明当前x是最大答对率或小于最大答对率,否则表示当前x大于最大答对率。

精度调高才能A

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define maxn 10100
int n,m,k;
double a[maxn],b[maxn],c[maxn];
int cmp(double x,double y){return x>y;}
bool check(double x){
    memset(c,0,sizeof(c));
    for(int i=1;i<=n;i++)c[i]=a[i]-x*b[i];
    sort(c+1,c+n+1,cmp);
    double ans=0;
    for(int i=1;i<=k;i++)ans+=c[i];
    if(ans>=0)return 1;
    else return 0;
}
int main(){
    while(1){
        scanf("%d%d",&n,&m);
        if(n==0&&m==0)return 0;
        k=n-m;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=1;i<=n;i++)scanf("%lf",&a[i]);
        for(int i=1;i<=n;i++)scanf("%lf",&b[i]);
        double l=0,r=1,ans;
        while(r-l>0.000001){
            double mid=(l+r)/2;
            if(check(mid))ans=mid,l=mid;
            else r=mid;
        }
        int x=floor(r*100+0.5);
        printf("%d
",x);
    }
}
原文地址:https://www.cnblogs.com/thmyl/p/7045139.html