今年有 n 场 ACM-ICPC 竞赛,小明每场都有资格参加。第 i 场竞赛共有 b[i] 道题。小明预测第 i 场他能做出 a[i] 道题。为了让自己看着更“大佬”一些,小明想让自己平均做出的题数越大越好,也就是最大化大佬度,大佬度的定义如下:
为了达到这个目的,小明决定放弃 k 场比赛的参赛资格。请求出最大的大佬度。
例如有 3 场小型比赛,题数分别是 5 题、1 题、6 题,小明预测自己分别能做出 5 题、0题、2题。如果每场都参加,那么大佬度是 ,看着不怎么大佬。不过,如果放弃第 3 场比赛,那么大佬度就是 ,看着更加大佬了。
输入测试文件含有多组测试,每组有 3 行。第一行有 2 个整数, 1 ≤ n ≤ 1000 和 0 ≤ k< n。第二行有 n 个整数,即每个 a[i]。第三行含有 n 个正整数 b[i]。保证 0 ≤ a[i] ≤ b[i] ≤ 1, 000, 000, 000。文件末尾由 n = k = 0 标识,并且不应该被处理。
对于每组测试数据,输出一行整数,即放弃 k 场比赛后可能的最高大佬度。大佬度应该舍入到最近的整数。
3 1 5 0 2 5 1 6 4 2 1 2 7 9 5 6 7 9 0 0
83 100
为了避免舍入误差带来的二义性,所有答案与除法边界相差至少 0.001 (例如答案永远不可能出现 83.4997)。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define eps 1e-6
int n, k;
double a[1005];
double b[1005];
double divide[1005];
int judge(double x) {
double sum = 0;
for(int i = 0; i < n; i++) {
divide[i] = a[i] - x*b[i];
}
sort(divide, divide+n);
for(int i = k; i < n; i++) {
sum += divide[i];
}
if(sum < 0) return 0;
return 1;
}
int main() {
while(~scanf("%d %d", &n, &k) && (n+k)) {
for(int i = 0; i < n; i++) scanf("%lf", &a[i]);
for(int i = 0; i < n; i++) scanf("%lf", &b[i]);
double left = 0, right = 1, mid;
while(right - left > eps) {
mid = (left+right)/2;
if(judge(mid)) left = mid;
else right = mid;
}
printf("%.f\n", right*100);
}
return 0;
}