列表

详情


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;
}

上一题