poj2976 Dropping tests
Dropping tests
题目大意:
在一场测试中有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\n",x); } }