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; }