C. Phoenix and Towers
这题让我们把n个block分成m个塔,让它们的高度差不超过x。
因为每个block的高度不超过x,首先m个block就分给前m个塔,然后每次往高度最小的塔上加block,这样得到的总是合法的。因为得到的不会和别的塔相差x。
代码
int main()
2 {
3 ios::sync_with_stdio(false); cin.tie(nullptr);
4
5 int t;
6 cin >> t;
7 while (t--) {
8 int n, m, x;
9 cin >> n >> m >> x;
10 cout << "YES" << endl;
11 set> s;
12 for (int i = 1; i <= m; i++) {
13 s.insert({ 0,i });
14 }
15 for (int i = 1; i <= n; i++) {
16 int tmp;
17 cin >> tmp;
18 pair p= *s.begin();
19 s.erase(s.begin());
20 cout << p.second << " ";
21 s.insert({ p.first + tmp,p.second });
22 }
23 cout << endl;
24 }
25
26 }
D. Phoenix and Socks
匹配袜子,这题我比赛时写出来了!
代码
1 int main()
2 {
3 ios::sync_with_stdio(false); cin.tie(nullptr);
4
5 int t;
6 cin >> t;
7 while (t--) {
8 int n, l, r;
9 cin >> n >> l >> r;
10 memset(L, 0, sizeof(L));
11 memset(R, 0, sizeof(R));
12 for (int i = 1; i <= n; i++) {
13 int tmp;
14 cin >> tmp;
15 if (i <= l) //因为颜色的种类也就n种,不多。先桶排序,把颜色相同的放在一起
16 L[tmp]++;
17 else
18 R[tmp]++;
19 }
20 for (int i = 1; i <= n; i++) {
21 int mi = min(L[i], R[i]); //有的不需要操作,直接匹配
22 L[i] -= mi;
23 R[i] -= mi;
24 l -= mi;
25 r -= mi;
26 }
27
28 if (l < r) {
29 swap(L, R);
30 swap(l, r);
31 }
32
33 int dif = (l - r) / 2;
34 int ans = 0;
35 for (int i = 1; i <= n; i++) {
36 if (dif >= L[i] / 2) { //再将多的那种袜子的颜色相同的进行转换操作
37 dif -= L[i] / 2; //但最多只转换dif次,不能多了
38 ans += L[i] / 2;
39 L[i] %= 2;
40 }
41 else {
42 ans += dif;
43 dif = 0;
44 break;
45 }
46 }
47
48 ans += r + 2 * dif; //最后将剩下的dif进行2次操作,r个直接变颜色
49 cout << ans << endl;
50 }
51 }