Sicily 2015 A New Year Gift

来源:互联网 发布:数据监测平台 编辑:程序博客网 时间:2024/05/17 22:26

一开始的想法是直接模拟,但是提交之后发现会超时。参考了各位大神的思路,采用二分逼近查找。最终的种类数量肯定在最低值0与最高值sum/m(总珍珠数/组数)之间。每次去中间值进行逼近,知道bot > top为止。采用贪心算法,不用考虑具体实现,每次只要取种类数和每种的个数中的较小值即可。最终对二分逼近的值进行判断,若能组成则输出,否则减一输出

// Problem#: 2015// Submission#: 3269318// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen University#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int main() {    int m, n;    int top, bot, mid;    int a[1005];    int sum = 0;    while (scanf("%d", &n) && n) {        sum = 0;        for (int i = 0; i < n; i++) {            scanf("%d", &a[i]);            sum += a[i];        }        scanf("%d", &m);                bot = 0;  //  低值        top = sum / m;  //  高值        while (bot < top) {  //  判断终止条件            mid = (bot + top) / 2;  // 二分中值逼近            sum = 0;            for (int i = 0; i < n; i++) {                sum += min(mid, a[i]);            }            sum >= mid * m ? bot = mid + 1: top = mid - 1;  //  改变bot 或top        }        sum = 0;        for (int i = 0; i < n; i++) {  //  判断是否可以组成二分逼近的结果            sum += min(bot, a[i]);        }        printf("%d\n", sum >= bot * m ? bot : bot - 1);     }}                                 


0 0