B - Dropping tests

今年有 n 场 ACM-ICPC 竞赛,小明每场都有资格参加。第 i 场竞赛共有 b[i] 道题。小明预测第 i 场他能做出 a[i] 道题。为了让自己看着更“大佬”一些,小明想让自己平均做出的题数越大越好,也就是最大化大佬度,大佬度的定义如下:

为了达到这个目的,小明决定放弃 k 场比赛的参赛资格。请求出最大的大佬度。

例如有 3 场小型比赛,题数分别是 5 题、1 题、6 题,小明预测自己分别能做出 5 题、0题、2题。如果每场都参加,那么大佬度是 ,看着不怎么大佬。不过,如果放弃第 3 场比赛,那么大佬度就是 ,看着更加大佬了。

Input

输入测试文件含有多组测试,每组有 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 标识,并且不应该被处理。

Output

对于每组测试数据,输出一行整数,即放弃 k 场比赛后可能的最高大佬度。大佬度应该舍入到最近的整数。

Sample Input

3 1
5 0 2
5 1 6
4 2
1 2 7 9
5 6 7 9
0 0

Sample Output

83
100

Hint

为了避免舍入误差带来的二义性,所有答案与除法边界相差至少 0.001 (例如答案永远不可能出现 83.4997)。

一开始一直搞不明白,后来稍微懂了一点,方法是二分,二分的思想就是折半,其实就是在一个给定区间里查找到一个满足条件的数,如本题,\sum ai/\sum bi=k,就是让你去求k的最大值,并且它的区间一定是[0,1],我们得找到某个条件才能去不断的二分缩小区间,那么条件就是\sum ai-k*\sum bi最大时,如果>0(就是\sum ai/\sum bi>k),意思是当前的k比最大值小,最大值可以在当前的k的基础上往上走,所以移动下边界;反之移动上边界;当边界非常接近时(所要求的精度,直接设置较大精度即可)停止。

重要的是就是写d[ ]数组,也就是如何表现条件,这里的d数组存的是ai-k*bi的值,然后将d数组从小到大排序,求出最大的\sum ai-k*\sum bi,比较。

唉~,本人实在太菜,只能这样浅薄的理解,可能还会有错误,欢迎指正。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#define eps 1e-7

using namespace std;

int main()
{
    int n,m;
    while( ~scanf("%d%d",&n,&m))
   {
        if(n==0&&m==0) break;
        double a[2000],b[2000],d[2000];
        for(int i=0;i<n;i++)
            scanf("%lf",&a[i]);
        for(int i=0;i<n;i++)
            scanf("%lf",&b[i]);

        double l=0.0,r=1.0,mid=0.0;
        while(r-l>eps){
             mid=(r+l)/2;//here is "+"!!!WA many!!
             for(int i=0;i<n;i++)
                 d[i]=a[i]-mid*b[i];
             sort(d,d+n);
             double sum=0.0;
             for(int i=m;i<n;i++)
                sum+=d[i];
             if(sum>0)  l=mid;
             else r=mid;
        }

    printf("%.0f\n",mid*100);//注意输出double时用%f,四舍五入保留小数就直接%.0f!!!
                             //这里出错导致WA了好多次!!!一定要谨记!!!
   }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值