zoukankan      html  css  js  c++  java
  • 2016-2017 ACM-ICPC, NEERC

    CodeForces - 730A

    题意

    给你一些分数,让你每次选2-5个数掉1分,最后使得所有人分数相等。求最后每个人的分数的最大值,并且输出一个方案,不用步骤最少,只要输出每次选哪些人掉分即可。

    思路

    要思来想去可以摸索到,可以枚举最后的分数R,每次看看可不可行。减掉以后,如果有一个比其他数大很多,那么其他数可能不能和他一起被削掉,所以只好R再小一点,多点数可以消。如果足够的话,可以猜想,假如总分是偶数这样必然有办法可以逐对消光,加入总分是奇数,就是先扣掉三个人的分数,然后逐对地掉分。

    这样最坏情况就是到0都不够最大的数掉分,那就随便消了。

    但是也有情况可能有一个分数就是0,那么还要考虑一下是不是可以随便来。

    反正最后消去的过程是类似的,通过优先队列模拟这个过程就好了。

    代码

    #define DEBUG(x) cerr<<"    DBG::>>"<<#x<<" = "<<(x)<<";"<<endl
    
    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <string.h>
    #include <set>
    #include <string>
    
    using namespace std;
    typedef long long ll;
    const int MAXN = 1005;
    const int INF = 0x3f3f3f3f;
    const ll MOD = 1e9 + 7;
    
    struct node {
        int i, v;
    
        bool operator<(const node &T) const {
            return v < T.v;
        }
    };
    
    int kase;
    int n, r;
    int a[MAXN];
    int sum, maxi, mini;
    priority_queue<node> que;
    
    void outPrint(const vector<node> &args) {
        string out;
        out.append(n, '0');
        for (auto item : args) { out[item.i - 1] = '1'; }
        cout << out << endl;
    }
    
    void dropItem(const int &num) {
        vector<node> tmp(num);
        for (auto &item:tmp) {
            item = que.top();
            que.pop();
            item.v = max(0, item.v - 1);
        }
        outPrint(tmp);
        for (auto item:tmp) {
            que.emplace(item);
        }
    }
    
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cout.tie(nullptr);
    
        mini = INF;
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            cin >> a[i];
            sum += a[i];
            maxi = max(maxi, a[i]);
            mini = min(mini, a[i]);
            que.emplace((node) {i, a[i]});
        }
    
        for (r = mini; r > 0; --r) {
            if (sum - maxi - r * (n - 1) >= maxi - r) {
                break;
            }
        }
        cout << r << endl;
    
        if (r == 0) {
            cout << max(sum / 2, maxi) << endl;
        } else {
            cout << (sum - r * n) / 2 << endl;
        }
    
        if ((sum - r * n) % 2 > 0 && n > 2) {
            dropItem(3);
        }
        while (que.top().v > r) {
            dropItem(2);
        }
    
        return 0;
    }
    /*
    
     * */
    
    
  • 相关阅读:
    平衡二叉树
    二叉搜索树的最近公共祖先
    U-Boot> help, 命令集
    sprintf_s函数用法
    用keil编写的 C51错误 *** WARNING L1: UNRESOLVED EXTERNAL SYMBOL SYMBOL: ?C_START
    GPS时间系统概述和世界时系统
    浅析gcc、arm-linux-gcc和arm-elf-gcc关系
    如何删除电脑中使用过的COM端口
    飞鸽传书 绑定指定网卡
    UE 高亮 一个或多个关键字的方法
  • 原文地址:https://www.cnblogs.com/tieway59/p/10923861.html
Copyright © 2011-2022 走看看