zoukankan      html  css  js  c++  java
  • POJ:2976-Dropping tests(二分平均值)

    Dropping tests

    Time Limit: 1000MS Memory Limit: 65536K
    Total Submissions: 15508 Accepted: 5418

    Description

    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 100*sum(ai)/sum(bi)

    .

    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 .

    Input

    The input test file will contain multiple test cases, each containing exactly three lines. The first line contains two integers, 1 ≤ n ≤ 1000 and 0 ≤ k < n. 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 0 ≤ ai ≤ bi ≤ 1, 000, 000, 000. The end-of-file is marked by a test case with n = k = 0 and should not be processed.

    Output

    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.

    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

    To avoid ambiguities due to rounding errors, the judge tests have been constructed so that all answers are at least 0.001 away from a decision boundary (i.e., you can assume that the average is never 83.4997).


    中文题意:

    今年有 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 场比赛后可能的最高大佬度。大佬度应该舍入到最近的整数。
    

    解题心得:

    1. 其实就是一个最大化平均值的问题,最大化平均值二分的一种经典应用,先假设答案为ans,如果100 * sum(ai) / sum(bi) > ans,那么按照这种大于/小于的关系式来二分答案,但是在运算的时候需要转化一下关系式,可以转换成:100 * sum(ai) > sum(bi) * ans,按照乘法的分配律可以写成100 * sum(ai) > sum(bi * ans),然后移项得到关系式:100 * sum(ai) - sum(bi * ans) > 0,然后按照减法的分配律可以写成sum(100 * ai - bi * ans) > 0,这样可以先得出100 * ai-bi * ans,然后降序排序,算出前n - k个是否大于0,然后以此二分就行了。

    #include <algorithm>
    #include <cstring>
    #include <stdio.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1010;
    ll n,k,a[maxn],b[maxn];
    double c[maxn];
    
    void init() {
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]);
        for(int i=0;i<n;i++)
            scanf("%lld",&b[i]);
    }
    
    bool cmp(double a,double b) {
        return a > b;
    }
    
    bool checke(double va) {
        for(ll i=0;i<n;i++)
            c[i] = (double)a[i]*100.0 - va*b[i];
        sort(c,c+n,cmp);
        double sum = 0;
        for(int i=0;i<n-k;i++)
            sum += c[i];
        return sum >= 0;
    }
    
    double binary_search() {
        double l,r;
        l = 0, r = 1e18+100;
        for(int i=0;i<100;i++) {//为了保证精度问题直接循环100次
            double mid = (l + r) / 2.0;
            if(checke(mid))
                l = mid;
            else
                r = mid;
        }
        return l;
    }
    
    int main() {
        while(scanf("%lld%lld",&n,&k) && n|k) {
            init();
            double ans = binary_search();
            ll int_ans = (ans + 0.5);
            printf("%lld
    ",int_ans);
        }
        return 0;
    }
  • 相关阅读:
    ScreenToGif 使用教程
    无问西东
    php如何解决中文乱码问题?
    layer父页面调用子页面的方法
    弹层组件文档
    关于svn获取获取文件时 Unable to connect to a repository at URL"https://..."执行上下文错误:参数错误
    centos下修改文件后如何保存退出
    Linux CentOS 7的图形界面安装(GNOME、KDE等)
    CentOS7安装详解
    Could not attach to pid : "xx"最近启动Xcode运行项目都会出现这个问题,再次启动或者多启动几次,就可以正常运行工程了。
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107122.html
Copyright © 2011-2022 走看看