NC51093. Dropping tests
描述
In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cumulative average is defined to be
.
Given your test scores and a positive integer k, determine how high you can make your cumulative average if you are allowed to drop any k of your test scores.
Suppose you take 3 tests with scores of 5/5, 0/1, and 2/6. Without dropping any tests, your cumulative average is . However, if you drop the third test, your cumulative average becomes .
输入描述
The input test file will contain multiple test cases, each containing exactly three lines. The first line contains two integers, and The second line contains n integers indicating ai for all i. The third line contains n positive integers indicating bi for all i. It is guaranteed that The end-of-file is marked by a test case with n = k = 0 and should not be processed.
输出描述
For each test case, write a single line with the highest cumulative average possible after dropping k of the given test scores. The average should be rounded to the nearest integer.
示例1
输入:
3 1 5 0 2 5 1 6 4 2 1 2 7 9 5 6 7 9 0 0
输出:
83 100
C++(g++ 7.5.0) 解法, 执行用时: 17ms, 内存消耗: 444K, 提交时间: 2023-01-29 06:59:09
#include<cmath> #include<cstdio> #include<vector> #include<algorithm> #include<functional> int main() { for(int n,k;scanf("%d%d",&n,&k),n|k;) { std::vector<int> a(n),b(n); for(auto&i:a)scanf("%d",&i); for(auto&i:b)scanf("%d",&i); auto check=[&](double ans)->bool { std::vector<double> c(n);double res=0; for(int i=0;i<n;i++)c[i]=a[i]-ans*b[i]; std::nth_element(c.begin(),c.begin()+n-k,c.end(),std::greater<double>()); for(int i=0;i<n-k;i++)res+=c[i]; return res>=0; }; auto work=[&]() { double l=0,r=1,mid; while(r-l>1e-6) { if(check(mid=(l+r)/2))l=mid; else r=mid; } printf("%.0f\n",round(100*mid)); }; work(); } return 0; }
C++14(g++5.4) 解法, 执行用时: 39ms, 内存消耗: 480K, 提交时间: 2020-03-27 13:48:44
#include<bits/stdc++.h> using namespace std; typedef long long ll; double a[1005],b[1005],d[1005];int n,k; bool check(double mid) { for(int i=1;i<=n;i++){ d[i]=a[i]-mid*b[i]; } sort(d+1,d+1+n);double rec=0; for(int i=k+1;i<=n;i++){ rec+=d[i]; } if(rec>0) return true; return false; } int main() { while(~scanf("%d%d",&n,&k)){ if(n==k&&k==0) break; if(k==n) k--; 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; while(r-l>=1e-6){ //cout<<l<<" "<<r<<endl; double mid=(l+r)/2; if(check(mid)) l=mid; else r=mid; } printf("%.0lf\n",l*100); } }
C++ 解法, 执行用时: 41ms, 内存消耗: 388K, 提交时间: 2022-01-07 21:18:04
#include<bits/stdc++.h> using namespace std; double a[1010],b[1010],c[1010]; int n,k; bool check(double x){ for(int i=1;i<=n;i++)c[i]=a[i]-x*b[i]; sort(c+1,c+n+1); double ans=0; for(int i=k+1;i<=n;i++)ans+=c[i]; return ans>0; } int main(){ while(cin>>n>>k){ if(n==0&&k==0)break; for(int i=1;i<=n;++i)cin>>a[i]; for(int i=1;i<=n;++i)cin>>b[i]; double L=0.0,R=1.0,mid; while(R-L>1e-8){mid=(L+R)/2.0;if(check(mid))L=mid;else R=mid;} printf("%.0lf\n",L*100); } return 0; }