UVa 11100 - The Trip, 2007 难度: 0

题目

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2674


题意

n个正整数,尽量均匀地把它们分成严格递增序列。要求序列个数最小

 

思路

明显,序列个数就是出现最多次的正整数的次数。接下来只要循环着由小到大把数字放进各个序列中就可以了。

 

感想:

读了好几遍都没读懂题目“While maintaining the minimal number of pieces you are also to minimize the total number of bags in any one piece that must be carried”

 

代码

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#define LOCAL_DEBUG
using namespace std;
typedef pair<int, int> MyPair;
const int MAXN = 1e4 + 4;
const int MAXA = 1e6 + 6;
MyPair a[MAXN];
int cnt[MAXA];
int cap[MAXA];

int main() {
#ifdef LOCAL_DEBUG
    freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\input.txt", "r", stdin);
    //freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\output.txt", "w", stdout);
#endif // LOCAL_DEBUG
    int T, n;
    for (int ti = 1;cin>>n && n; ti++) {
        memset(cnt, 0, sizeof cnt);
        for (int i = 0; i < n; i++) {
            int tmp;
            cin >> tmp;
            cnt[tmp] ++;
        }
        int ans = 0;
        int newn = 0;
        for (int i = 1; i < MAXA; i++) {
            ans = max(ans, cnt[i]);
        }
        int cap_all = (n + ans - 1) / ans;
        for (int i = 0; i <= ans; i++) {
            cap[i] = cap_all;
        }
        int cid = 0;
        int cidnow = 0;
        for (int i = 1; i < MAXA; i++) {
            ans = max(ans, cnt[i]);
            while (cap[cid] == 0) {
                cid++;
            }
            while (cnt[i]) {
                a[newn].first = cidnow;
                a[newn].second = i;
                newn++;
                cnt[i]--;
                cap[cidnow]--;
                cidnow=(cidnow - cid + 1) % (ans - cid)  + cid;
            }
        }
        sort(a, a + n);
        if (ti > 1)cout << endl;
        cout << ans << endl;
        for (int i = 0; i < n; i++) {
            if (i && a[i].first != a[i - 1].first)cout << endl;
            else if (i)cout << " ";
            cout << a[i].second;
        }
        cout << endl;
    }

    return 0;
}
View Code

 

posted @ 2019-03-05 19:01  雪溯  阅读(110)  评论(0编辑  收藏  举报