我解决的:D、I、E。

没看的:H、K。

旁观的:B、G。

看了但没做出来的:A、C、F、J。

E Life Transfer

简单题,略。

D Cycle String?

题意:给定一个长为 2N2N2N 的串,问能否将其重新排列使得新串的每一个长度为 NNN 的循环子串(即这个子串可以由原串的某个后缀和前缀拼接而成)互不相同,如果能要给出一个构造。

统计每一个字符出现的数目,然后分类讨论。

  1. 只有一种字符,那必然无解。
  2. 只有两种字符,且某种字符出现了不少于 2N−22N-22N−2 次,那么就可能无解,要看 NNN 是否为 111 或者 222,或者大于 222。这里讨论一下即可。
  3. 除上面两种情况外都是有解的。设出现次数最多的字符为 aaa,如果 aaa 出现了不超过 NNN 次,那么只要对原字符串排序即可;否则在排序完原字符串后,要用一个除 aaa 之外的字符把那一段 aaa 分割为左右两部分,使得左半部分长度恰为 NNN。可以证明这一构造是合法的。

K Stranded Robot

大模拟,略。应该不是很难写…

G Projection

题意:有一个 n×m×hn \times m \times hn×m×h 的三维网格,每一个网点上可能有一个方块。给定这个网格沿着两个方向投影得到的画面,大小分别为 n×mn \times mn×m 和 n×hn \times hn×h,问为了达成这样的投影,这个网格中最多要有几个方块、最少要有几个方块,并给出两种情况下方块的坐标列表。多解时输出字典序最小的那个。

按 nnn 坐标遍历,每一层进行构造。显然,每一层的答案互不影响。

无解当且仅当这一层在 n×mn\times mn×m 的投影中有影子,但在 n×hn\times hn×h 的投影中没有影子,或者反过来。

如果这一层在 n×mn\times mn×m 的投影中有 aaa 个方块的影子,在 n×hn\times hn×h 的投影中有 bbb 个方块的影子,那么这一层最多可以有 aba bab 个方块,最少可以有 max⁡(a,b)\max(a, b)max(a,b) 个方块。

对于后者要求出字典序最小的方案,只需要按照 mmm 坐标或者 hhh 坐标递增方向构造方块即可。

#include <bits/stdc++.h>
#define MAXN 105
using namespace std;
int n, m, h, a[MAXN][MAXN], b[MAXN][MAXN];
int cntm[MAXN], cnth[MAXN];
int lstm[MAXN], lsth[MAXN];
char s[MAXN];
int main(){scanf("%d%d%d", &n, &m, &h);for (int i = 1; i <= n; ++i){scanf("%s", s + 1);cntm[i] = 0;for (int j = 1; j <= m; ++j)a[i][j] = (s[j] == '1' ? 1: 0), cntm[i] += a[i][j];}for (int i = 1; i <= n; ++i){scanf("%s", s + 1);cnth[i] = 0;for (int j = 1; j <= h; ++j)b[i][j] = (s[j] == '1' ? 1: 0), cnth[i] += b[i][j];}// -1int maxi = 0, mini = 0;for (int i = 1; i <= n; ++i){if ((cntm[i] > 0 && cnth[i] == 0) || (cnth[i] > 0 && cntm[i] == 0)){printf("-1\n");return 0;} maxi += cntm[i] * cnth[i];mini += max(cntm[i], cnth[i]);}// constructprintf("%d\n", maxi);for (int i = 1; i <= n; ++i){for (int j = 1; j <= m; ++j)for (int k = 1; k <= h; ++k)if (a[i][j] && b[i][k]) printf("%d %d %d\n", i - 1, j - 1, k - 1);}printf("%d\n", mini);for (int i = 1; i <= n; ++i){if (!cntm[i]) continue;int totm = 0, toth = 0;for (int j = 1; j <= m; ++j)if (a[i][j]) lstm[++totm] = j;for (int j = 1; j <= h; ++j)if (b[i][j]) lsth[++toth] = j;for (int j = 1, k = 1; j <= totm; ){printf("%d %d %d\n", i - 1, lstm[j] - 1, lsth[k] - 1);if (totm - j == toth - k){++j, ++k;} else if (totm - j > toth - k){++j;} else {++k;}}}return 0;
}

F Game on a Tree

题意:给定一个以 111 为根的树,一开始所有节点都是白色。A 先手将一个棋子放在某个节点,棋子会把所在节点涂黑。随后 B 和 A 轮流移动棋子,棋子不能跨过黑色节点,且只能移动到当时所在节点的祖先,或者子树中的某个节点。不能移动者输。问双方均采取最优策略时,谁赢。

这貌似是一个很经典的博弈论问题。如果将所有互相可达的点之间连一个边,得到一个新的无向图,那么结论就是:如果这个无向图的最大匹配是完美匹配,那么后手必胜;否则先手必胜。

为了求出新图的最大匹配,我们设 f(i)f(i)f(i) 表示 iii 号点的子树中,在最大匹配的情况下,还有多少个点没有被匹配。

设 iii 的所有儿子的 fff 值加起来为 tottottot。若其不为 0,那么 iii 就与 tottottot 个未匹配点中的一个匹配,f(i)=tot−1f(i) = tot-1f(i)=tot−1。否则 iii 不被匹配,f(i)=1f(i) = 1f(i)=1。

所以按上述说明 DP 一下,检查 f(1)f(1)f(1) 即可。

B Level Up

题意:有 nnn 个任务,现在要尽快通过两个关卡,一开始处于第一关,通过第一关就到达第二关。通过第一、二关各要 s1,s2s_1, s_2s1​,s2​ 经验。到第二关时,原有的 s1s_1s1​ 经验会清零。如果通过第一关时经验超过 s1s_1s1​,溢出的部分会继承到第二关。给定每一个任务在第一、二关时完成可获得的经验和所需时间,求最短通关时间。

我们同时考虑两个关卡,设 f(i,j,k)f(i, j, k)f(i,j,k) 为用前 iii 个任务,第一关达到 jjj 经验,第二关达到 kkk 经验时的最短时间。则转移方程容易写出。

一个坑点在于我们必须按照“在第一关时完成可获得的经验”从小到大来遍历任务,否则无法正确处理经验溢出的情况:考虑 s1=s2=60s_1 = s_2 = 60s1​=s2​=60,只有两个任务 a,ba, ba,b,aaa 在第一关通过获得经验 303030,bbb 为 909090,两者在第二关通过时均不获得经验。如果 bbb 在 aaa 前被枚举,那么会被判无解,反之有解。

DP 的第一维可以用滚动数组优化。

I Absolute Game

题意:A 和 B 两个人各有 NNN 个数,有 N−1N-1N−1 轮游戏,每一轮两个人要轮流删掉自己的一个数。A 先手。假设最后 A,B 手上的数分别为 a,ba, ba,b,A 希望最大化两者差的绝对值,B 希望最小化两者差的绝对值。问两人均采取最优策略时,最后这个差的绝对值。

设 A 有数 {ai}\left\lbrace a_i \right\rbrace{ai​},B 有数 {bi}\left\lbrace b_i \right\rbrace{bi​}。问题等价于 A 选一个 iii,然后最大化 min⁡1≤j≤n∣ai−bj∣\min_{1 \le j \le n} |a_i - b_j|min1≤j≤n​∣ai​−bj​∣。

于是就很简单了。但是最难的在于这个等价性是怎么来的呢?我不会证,不如参考官方题解。

J Graph and Cycles

题意:给定一个 NNN 个点的带权无向完全图,保证 NNN 是奇数。定义环 e1,e2,⋯,eke_1, e_2, \cdots, e_ke1​,e2​,⋯,ek​ 的价格为 ∑i=1kmax⁡(w(ei),w(ei+1))\sum_{i=1}^{k} \max(w(e_i), w(e_{i+1}))∑i=1k​max(w(ei​),w(ei+1​)),其中 ek+1=e1e_{k+1} = e_1ek+1​=e1​。现在要将图分割成若干个环,使得每一个环的价格之和最小。求这个价格。

由于 NNN 是奇数,因此每一个点的度为偶数。可以看出,如果一个环经过点 vvv,那么一定有一条边进入 vvv,另一条走出 vvv。

对每一个点 vvv,其连着的边可以分成 N−12\frac{N-1}{2}2N−1​ 组,每组属于某个环,一条进入 vvv,另一条走出 vvv。每组中权值较大的边就是这组边对价格的贡献。因此所有环的价格和就等于若干组边的价值和。

到这一步,只要恰当的分组使得价格尽量小即可。最好的分组方式就是排序后按顺序两两分组。这样就求出了答案。

但怎么说明这样转化后,一定有相对应的环分割呢?我也不会证,不如参考官方题解。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
vector<int> G[1005];
int main(){scanf("%d", &n);int u, v, w;while (~scanf("%d%d%d", &u, &v, &w)){G[u].push_back(w);G[v].push_back(w);}ll ans = 0;for (int i = 1; i <= n; ++i){sort(G[i].begin(), G[i].end());for (int j = 1; j < n - 1; j += 2)ans += G[i][j];}printf("%lld\n", ans);return 0;
}

C Find the Array

题意:交互题。有一个长为 n≤250n \le 250n≤250 的数组,里面的数互不相同,且开始时未知。有两种操作:操作 1 直接获取一个下标上的值,操作 2 接受若干下标,设为 kkk 个,获得这些下标上的数两两做差的绝对值,共 k(k−1)2\frac{k(k-1)}{2}2k(k−1)​ 个(无序)。在 30 次操作内找出这个数组。

本题有一个很妙的做法。先用操作 2 输入所有下标,找出极差 ddd,其必然是两个最值的差。然后我们希望找到一个最小的 pospospos,使得 aaa 的最值均在 [1,pos][1, pos][1,pos] 内。这个可以二分处理。

然后针对 pospospos,我们希望对于所有 i≠posi \neq posi​=pos,找出 bi=∣ai−apos∣b_i = |a_i - a_{pos}|bi​=∣ai​−apos​∣。这可以用二进制分组实现:枚举从低位到高位每一个 bit,设该 bit 为 2u2^u2u,设与该 bit 有交(即按位与不为 0)、且不等于 pospospos 的下标集合为 BuB_uBu​,把 Bu∪{pos}B_u\cup \left\lbrace pos \right\rbraceBu​∪{pos} 输入给操作 2,然后再把 BuB_uBu​ 输入给操作 2,把前者的结果除掉后者的结果,就得到了对任意 i∈Bui \in B_ui∈Bu​ 的 bib_ibi​ 构成的集合,记为 CuC_uCu​。

我们已经知道了 bbb 数组的所有值(共 n−1n-1n−1 个),现在要把值和下标关联起来。这是二进制分组的常规操作:对于每一个值,检查其对于每一个 bit 2u2^u2u,是否在 CuC_uCu​ 中出现。把所有出现了的 bit 或起来就是下标。

得到了 bbb 数组就可以知道另一个极值在哪,设为 pos′pos'pos′。用两次操作 1 获得 aposa_{pos}apos​ 和 apos′a_{pos'}apos′​,然后就可以方便地利用 bbb 数组求出 aaa 数组了。

总操作数不超过 1+⌈log⁡n⌉+2⌈log⁡n⌉+2≤271 + \lceil \log n\rceil + 2 \lceil \log n\rceil + 2 \le 271+⌈logn⌉+2⌈logn⌉+2≤27。

注意特判一些特殊情况,如操作 2 必须接受至少 2 个数。

#include <bits/stdc++.h>
using namespace std;
int n, a[255], b[255], lst[255], tot;
unordered_multiset<int> st[13];
unordered_set<int> sttot;
int getmaxi(int l){int maxi = 0;l = l * (l - 1) >> 1;for (int i = 1, t; i <= l; ++i){scanf("%d", &t);maxi = max(maxi, t);}return maxi;
}
int main(){scanf("%d", &n);// find the maximum differeceif (n == 1){printf("1 1\n");fflush(stdout);scanf("%d", &a[1]);printf("3 %d\n", a[1]);return 0;    }printf("2 %d", n);for (int i = 1; i <= n; ++i)printf(" %d", i);putchar('\n');fflush(stdout);int maxi = getmaxi(n);// find the base positionint l = 2, r = n;while (r > l){int mid = (l + r) >> 1;printf("2 %d", mid);for (int i = 1; i <= mid; ++i)printf(" %d", i);putchar('\n');fflush(stdout);if (getmaxi(mid) == maxi) r = mid;else l = mid + 1;}// here, pos is l// group the number by bitsfor (int i = 1, logg = 0; i <= n; i <<= 1, ++logg){tot = 0;for (int j = 1; j <= n; ++j){if (!(i & j) || j == l) continue;lst[++tot] = j;}if (tot == 0) continue;printf("2 %d %d", tot + 1, l);for (int j = 1; j <= tot; ++j)printf(" %d", lst[j]);putchar('\n');fflush(stdout);for (int j = 1, t; j <= (tot + 1) * tot / 2; ++j){scanf("%d", &t);st[logg].insert(t);}if (tot > 1){printf("2 %d", tot);for (int j = 1; j <= tot; ++j)printf(" %d", lst[j]);putchar('\n');fflush(stdout);for (int j = 1, t; j <= (tot - 1) * tot / 2; ++j){scanf("%d", &t);st[logg].erase(st[logg].find(t));}}for (int x: st[logg])sttot.insert(x);}// find array bint logg = 0, p = -1;while ((1 << logg) <= n) ++logg;for (int x: sttot){int pos = 0;for (int i = 0; i < logg; ++i){if (st[i].count(x)) pos |= (1 << i);}b[pos] = x;if (x == maxi) p = pos;}// here, pos' is pprintf("1 %d\n", l);fflush(stdout);scanf("%d", &a[l]);printf("1 %d\n", p);fflush(stdout);scanf("%d", &a[p]);// calc the answerint sgn = (a[l] < a[p] ? 1: -1);printf("3");for (int i = 1; i <= n; ++i){if (i != l) a[i] = a[l] + sgn * b[i];printf(" %d", a[i]);}putchar('\n');fflush(stdout);return 0;
}

A Max or Min

待补。。。

H Tree Permutations

待补。。。

【解题总结】SEERC 2019(Codeforces Gym 102392)相关推荐

  1. Codeforces Gym 101173 CERC 16 D BZOJ 4790 Dancing Disks

    Codeforces Gym 101173 CERC 16 D & BZOJ 4790 Dancing Disks 强烈安利这道构造题目,非常有意思. 这里用到的思想是归并排序! 多路归并排序 ...

  2. Codeforces Gym 101086 M ACPC Headquarters : AASTMT (Stairway to Heaven)

    Codeforces Gym 101086 M ACPC Headquarters : AASTMT (Stairway to Heaven) 题目来源: Codeforces 题意: 给出一些比赛, ...

  3. [Codeforces Gym 101651/100725B] Banal Tickets

    Codeforces Gym 100725 题解: 先分两种情况, 积为000与积非0" role="presentation" style="position ...

  4. 2019湖南多校第4场(codeforces gym 101158)部分题解

    目录 A题:题目链接 B题:题目链接 C题:题目链接 D题:题目链接 A题:题目链接 题意:给定一个整数 n,代表有一个序列 1,2,3,4,...,n ,然后给定一个整数m, 接下来有 m 个数,代 ...

  5. Codeforces Gym 100513G G. FacePalm Accounting 暴力

    G. FacePalm Accounting Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513 ...

  6. Codeforces Gym 100269 Dwarf Tower (最短路)

    题目连接: http://codeforces.com/gym/100269/attachments Description Little Vasya is playing a new game na ...

  7. Codeforces Gym 100676G Training Camp 状压dp

    http://codeforces.com/gym/100676 题目大意是告诉你要修n门课,每门课有一个权值w[i], 在第k天修该课程讲获得k*w[i]的学习点数,给出了课程与先修课程的关系,要修 ...

  8. codeforces Gym 100338E Numbers (贪心,实现)

    题目:http://codeforces.com/gym/100338/attachments 贪心,每次枚举10的i次幂,除k后取余数r在用k-r补在10的幂上作为候选答案. #include< ...

  9. Codeforces Gym 100342J Problem J. Triatrip 求三元环的数量 bitset

    Problem J. Triatrip Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/at ...

最新文章

  1. 刻意练习:LeetCode实战 -- Task21. 二叉树的最大深度
  2. BZOJ2837 : 小强的形状
  3. ACL 2020 | 多跳问答的基于对齐的无监督迭代解释检索方法
  4. laravel 数据库获取值的常用方法
  5. SWT、JavaFx十种页面布局快速理解
  6. Office2021 和Microsoft 365分不清?这样选最划算
  7. Linux下常用操作汇总
  8. Qt5开发从入门到精通——第一篇概述
  9. 电脑ps计算机磨皮,ps脸部磨皮教程
  10. 当下移动互联网的6个泡沫,快要破了!
  11. 学妹跑过来问我为啥Xshell 打不开了,让我帮她处理下【手把手讲解】
  12. 什么是前端开发工程师
  13. Android 获取横竖屏状态
  14. FxFactory 7 for Mac(视觉特效软件包)
  15. 微信小程序显示空格符
  16. 关于计算机500字英语作文,500字英语作文
  17. java阿里云短信对接
  18. 小程序中使用web-view链接H5网页
  19. MySQL数据库从小白到小菜02
  20. BZOJ 4627回转寿司(值域线段树)

热门文章

  1. [Python] 让AI来解决数独和数独谜题
  2. STC8单片机OLED通过SPI硬件中断方式驱动——优化
  3. this.$nextTick
  4. navigation_plugin
  5. Pandoc中的Markdown语法
  6. matlab报错之未定义与 ‘double‘ 类型的输入参数相对应的函数 ‘tf‘
  7. 创业圈的钱都去哪儿了?AI算法正帮Facebook成为大赢家
  8. 硕士论文如何通过查重?
  9. 计算机图形学 多边形裁剪
  10. 电子科技大学人工智能期末复习笔记(四):概率与贝叶斯网络