Contest Info


[Practice Link](https://codeforc.es/contest/1178)

Solved A B C D E F1 F2 G H
6/9 O O O O O Ø - - -
  • O 在比赛中通过
  • Ø 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Solutions


A. Prime Minister

签到题。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define N 110
  4. int n, a[N], b[N];
  5. int main() {
  6. while (scanf("%d", &n) != EOF) {
  7. memset(b, 0, sizeof b);
  8. int sum = 0, other = 0;
  9. for (int i = 1; i <= n; ++i) scanf("%d", a + i), sum += a[i];
  10. b[1] = 1;
  11. other = a[1];
  12. for (int i = 2; i <= n; ++i) {
  13. if (a[1] >= a[i] * 2) {
  14. other += a[i];
  15. b[i] = 1;
  16. }
  17. }
  18. if (other > sum / 2) {
  19. int sze = 0;
  20. vector <int> vec;
  21. for (int i = 1; i <= n; ++i) {
  22. if (b[i]) {
  23. ++sze;
  24. vec.push_back(i);
  25. }
  26. }
  27. printf("%d\n", sze);
  28. for (int i = 0; i < sze; ++i) printf("%d%c", vec[i], " \n"[i == sze - 1]);
  29. } else {
  30. puts("0");
  31. }
  32. }
  33. return 0;
  34. }

B. WOW Factor

题意:

将连续的两个\(v\)可以看成一个\(w\),询问给出的字符串中只包含字符\(v\)和\(o\),询问有多少个子序列组成\(wow\)

思路:

先处理出每个\(o\)左边有多少个\(w\)以及右边有多少个\(w\),然后计算贡献即可。

代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define N 1000010
  5. int n;
  6. ll l[N], r[N];
  7. char s[N];
  8. int main() {
  9. while (scanf("%s", s + 1) != EOF) {
  10. n = strlen(s + 1);
  11. l[0] = 0;
  12. for (int i = 1; i <= n; ++i) {
  13. l[i] = l[i - 1];
  14. if (i > 1 && s[i] == 'v' && s[i - 1] == 'v') {
  15. ++l[i];
  16. }
  17. }
  18. r[n + 1] = 0;
  19. for (int i = n; i >= 1; --i) {
  20. r[i] = r[i + 1];
  21. if (i < n && s[i] == 'v' && s[i + 1] == 'v') {
  22. ++r[i];
  23. }
  24. }
  25. ll res = 0;
  26. for (int i = 1; i <= n; ++i) {
  27. if (s[i] == 'o') {
  28. res += 1ll * l[i - 1] * r[i + 1];
  29. }
  30. }
  31. printf("%lld\n", res);
  32. }
  33. return 0;
  34. }

C. Tiles

题意:

有这样的瓷砖:



用来拼\(n \cdot m\)的地板,要求任意相邻的边两边的颜色不能相同。

思路:

显然第一个位置可以有四种选择,并且第一排的后面的每个位置都有两种选择,因为不能和前面的边相同。

那么第一列后面的位置也有两种选择,那么剩下的位置都只有一种选择,因为它们相邻了两条边。

所以答案就是\(4 \cdot 2^{n + m - 2}\)

代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. const ll p = 998244353;
  5. ll qmod (ll base, ll n) {
  6. ll res = 1;
  7. while (n) {
  8. if (n & 1) {
  9. res = res * base % p;
  10. }
  11. base = base * base % p;
  12. n >>= 1;
  13. }
  14. return res;
  15. }
  16. int main() {
  17. int n, m;
  18. while (scanf("%d%d", &n, &m) != EOF) {
  19. printf("%lld\n", qmod(2, n - 1) * qmod(2, m - 1) % p * 4 % p);
  20. }
  21. return 0;
  22. }

D. Prime Graph

题意:

给出\(n\)个点,要求构成一个简单图,使得边的总数是素数,并且每个点的度数也是素数。

思路:

  • 首先考虑每个点的度数至少为\(2\),那么先把这些点连成一个环,所有点的度数就是\(2\)了。
  • 再考虑边的数量是素数,一个显然的想法是所有数都可以表示成\(2x + 3y\)的形式,所以我们将环中的点分成两部分,每次各取一个点连边,就增加一条边,并且让两个度数为\(2\)的点变成度数为\(3\)的。
  • 那么只要满足我们找一个\(>= n\)的最近的素数\(y\),使得\(y - n \leq \frac{n}{2}\)即可这样构造。
  • 素数的密度很高,或者\(n\)只有\(1000\)可以打表验证一下,这样是可以的。

代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define N 1010
  4. #define pii pair <int, int>
  5. #define fi first
  6. #define se second
  7. int n;
  8. bool isprime(int x) {
  9. for (int i = 2; i < x; ++i) {
  10. if (x % i == 0) return 0;
  11. }
  12. return 1;
  13. }
  14. int main() {
  15. while (scanf("%d", &n) != EOF) {
  16. int tot = n;
  17. for (int i = tot; ; ++i) {
  18. if (isprime(i)) {
  19. tot = i;
  20. break;
  21. }
  22. }
  23. vector <pii> vec;
  24. for (int i = 2; i <= n; ++i) vec.push_back(pii(i - 1, i));
  25. vec.push_back(pii(1, n));
  26. int remind = tot - n;
  27. int pos = n / 2 + 1;
  28. for (int i = 1; i <= remind; ++i) {
  29. vec.push_back(pii(i, pos));
  30. ++pos;
  31. }
  32. printf("%d\n", tot);
  33. for (auto it : vec) printf("%d %d\n", it.fi, it.se);
  34. }
  35. return 0;
  36. }

E. Archaeology

题意:

给出一个只包含'a', 'b', 'c'的字符串,保证任意两个连续的字符都不相同,要求选出一个子序列\(t\)使得它是一个回文串,并且\(|t| \geq \left\lfloor \frac{|s|}{2} \right\rfloor\)

思路:

贪心从两端取即可。

因为左端的两个字符和右端的两个字符,必然会有两个相等,因为保证了任意两个连续的字符不同,那么这样就是说每\(4\)个字符,至少有\(2\)个有贡献,显然满足题目限制。

其实也可以枚举一样,看看:

假如左端的\(ab\),那么右端的取值有以下几种:

  • \(ab\)
  • \(ac\)
  • \(bc\)

    显然都满足要求。

代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define N 1000010
  4. #define INF 0x3f3f3f3f
  5. int n, m, f[N][3], g[N][3], nx[3];
  6. char s[N], t[N];
  7. int vis[N];
  8. bool ok() {
  9. m = 0;
  10. for (int i = 1; i <= n; ++i) if (vis[i]) {
  11. t[++m] = s[i];
  12. }
  13. t[m + 1] = 0;
  14. if (m >= n / 2) {
  15. printf("%s\n", t + 1);
  16. return 1;
  17. }
  18. return 0;
  19. }
  20. int main() {
  21. while (scanf("%s", s + 1) != EOF) {
  22. n = strlen(s + 1);
  23. for (int i = 1; i <= n; ++i) vis[i] = 0;
  24. nx[0] = nx[1] = nx[2] = 0;
  25. for (int i = 1; i <= n + 1; ++i) {
  26. for (int j = 0; j < 3; ++j) {
  27. g[i][j] = nx[j];
  28. }
  29. if (i <= n) {
  30. nx[s[i] - 'a'] = i;
  31. }
  32. }
  33. nx[0] = nx[1] = nx[2] = n + 1;
  34. for (int i = n; i >= 0; --i) {
  35. for (int j = 0; j < 3; ++j) {
  36. f[i][j] = nx[j];
  37. }
  38. if (i > 0) {
  39. nx[s[i] - 'a'] = i;
  40. }
  41. }
  42. int l = 0, r = n + 1;
  43. while (l <= r) {
  44. int Min = INF, pos = -1;
  45. for (int i = 0; i < 3; ++i) {
  46. if (f[l][i] < g[r][i] && f[l][i] - l + r - g[r][i] < Min) {
  47. Min = f[l][i] - l + r - g[r][i];
  48. pos = i;
  49. }
  50. }
  51. if (pos == -1) break;
  52. l = f[l][pos];
  53. r = g[r][pos];
  54. vis[l] = vis[r] = 1;
  55. }
  56. if (l < r - 1) {
  57. vis[l + 1] = 1;
  58. }
  59. if (!ok()) printf("IMPOSSIBLE\n");
  60. }
  61. return 0;
  62. }

F1. Short Colorful Strip

题意:

有一个长度为\(n\)的方格纸,现在要求做\(n\)次涂刷操作,每次选择一个区间将其刷成颜色\(i\),刚开始全都为颜色\(0\),问最后方格纸上第\(i\)格颜色为\(c_i\)的方案数。

\(n = m\)。

思路:

令\(f[l][r]\)表示完成区间\([l, r]\)的涂刷的方案数。

考虑对于一个区间\([l, r]\),那么我们第一次涂的肯定是\(c_i\)最小的,然后以\(c_i\)最小的那个格子为界,划分成两边,令\(pos[i]\)表示当前区间\(c_i\)最小的格子的下标,那么有转移方程:

\[\begin{eqnarray*}
f[l][r] = \sum\limits_{a} \sum\limits_{b} f[l][a - 1] \cdot f[a][pos[i] - 1] \cdot f[pos[i] + 1][i - 1] \cdot f[i +1][r]
\end{eqnarray*}
\]

注意到划分出两个区间后,左边右边独立,所以可以分开计算,最后乘起来即可。

代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define N 510
  5. const ll p = 998244353;
  6. int n, m, a[N];
  7. ll f[N][N];
  8. void add(ll &x, ll y) {
  9. x += y;
  10. if (x >= p) x -= p;
  11. }
  12. ll dp(int l, int r) {
  13. if (l > r) return 1;
  14. if (f[l][r] != -1) return f[l][r];
  15. if (l == r) return f[l][r] = 1;
  16. f[l][r] = 0;
  17. int pos = l;
  18. for (int i = l + 1; i <= r; ++i) {
  19. if (a[i] < a[pos]) pos = i;
  20. }
  21. ll L = dp(l, pos - 1), R = dp(pos + 1, r);
  22. for (int i = l; i < pos; ++i) {
  23. add(L, dp(l, i) * dp(i + 1, pos - 1) % p);
  24. }
  25. for (int i = pos + 1; i <= r; ++i) {
  26. add(R, dp(pos + 1, i) * dp(i + 1, r) % p);
  27. }
  28. return f[l][r] = L * R % p;
  29. }
  30. int main() {
  31. while (scanf("%d%d", &n, &m) != EOF) {
  32. memset(f, -1, sizeof f);
  33. for (int i = 1; i <= n; ++i) scanf("%d", a + i);
  34. printf("%lld\n", dp(1, n));
  35. }
  36. return 0;
  37. }

Codeforces Global Round 4的更多相关文章

  1. CodeForces Global Round 1

    CodeForces Global Round 1 CF新的比赛呢(虽然没啥区别)!这种报名的人多的比赛涨分是真的快.... 所以就写下题解吧. A. Parity 太简单了,随便模拟一下就完了. B ...

  2. Codeforces Global Round 1 - D. Jongmah(动态规划)

    Problem   Codeforces Global Round 1 - D. Jongmah Time Limit: 3000 mSec Problem Description Input Out ...

  3. Codeforces Global Round 2 题解

    Codeforces Global Round 2 题目链接:https://codeforces.com/contest/1119 A. Ilya and a Colorful Walk 题意: 给 ...

  4. Codeforces Global Round 1 (A-E题解)

    Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^( ...

  5. Codeforces Global Round 3

    Codeforces Global Round 3 A. Another One Bites The Dust 有若干个a,有若干个b,有若干个ab.你现在要把这些串拼成一个串,使得任意两个相邻的位置 ...

  6. Codeforces Global Round 1 (CF1110) (未完结,只有 A-F)

    Codeforces Global Round 1 (CF1110) 继续补题.因为看见同学打了这场,而且涨分还不错,所以觉得这套题目可能会比较有意思. 因为下午要开学了,所以恐怕暂时不能把这套题目补 ...

  7. 【手抖康复训练1 】Codeforces Global Round 6

    [手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思 ...

  8. Codeforces Global Round 11 个人题解(B题)

    Codeforces Global Round 11 1427A. Avoiding Zero 题目链接:click here 待补 1427B. Chess Cheater 题目链接:click h ...

  9. 【Codeforces Round 1110】Codeforces Global Round 1

    Codeforces Round 1110 这场比赛只做了\(A\).\(B\).\(C\),排名\(905\),不好. 主要的问题在\(D\)题上,有\(505\)人做出,但我没做出来. 考虑的时候 ...

  10. 树形DP ---- Codeforces Global Round 2 F. Niyaz and Small Degrees引发的一场血案

    Aspirations:没有结果,没有成绩,acm是否有意义?它最大的意义就是让我培养快速理解和应用一个个未知知识点的能力. ————————————————————————————————————— ...

随机推荐

  1. conda命令入坑记

    conda命令入坑记 本人使用的软件版本: TypeError: LoadLibrary() argument 1 must be str, not None 网上太多的资料,大多都是在讲path的设 ...

  2. 最小轻量级的Istio来了,仅使用流量治理能力

    Istio 1.0.1作为8月份的版本已经发布,主要修复了1.0版本发布以来发现的一些关键Issue.官网的release note(https://istio.io/about/notes/1.0. ...

  3. 安利一下stringstream

    关于实用的 stringstream 处理毒瘤输入数据 比如这个题 在输入的时候有很多问题,如果用scanf输入char型字符串,那么不好用map判断,并且读入整行判断换行会很麻烦 如果选择用stri ...

  4. sqlserver 查看表死锁

    1.SELECT request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName FROM sys.dm_tr ...

  5. ajax提交异常解决

    一.遇到的问题 在项目中使用ajax提交表单失败,并且后台程序都没有执行,分析具体问题是由于post表单时contenttype的类型不一致. 二.解决方式 $.ajax({ type: 'post' ...

  6. PyCharm 占用过大 C 盘空间,system 配置文件迁移

    随着 PyCharm 的持续使用,对应 C:\Users\<username>\.PyCharm<2018.3> 下的文件大小会持续增大,且通常为 system 文件夹下的内容 ...

  7. pc端vue 滚动到底部翻页

    html: <div class="list" ref="scrollTopList"> <div class="listsmall ...

  8. npm查看包版本

    点击跳转 ~ 会匹配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x版本,但是不包括1.3.0 ^ 会匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,包括1.3.0,但是不包 ...

  9. 关于lock和synchronized的选择

    这里不介绍具体用法,介绍lock和synchronized的不同从而做出选择 1.lock是一个接口,而synchronized是java中的一个关键字,synchronized是内置的语言实现. 2 ...

  10. volatile和锁

    让编译器不要将变量缓存到寄存器,而是每次去访问主板上的内存 可见性 对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入 原子性 对任意单个volatile变量的 ...