比赛链接

A

题解

知识点:贪心。

下标模 \(k\) 相同分为一组,共有 \(k\) 组,组间不能互换,组内任意互换。

题目要求连续 \(k\) 个数字,一定能包括所有的 \(k\) 组,现在只要在每组中选取最大的加在一起即可。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. int a[107];
  5. bool solve() {
  6. int n, k;
  7. cin >> n >> k;
  8. for (int i = 1;i <= n;i++) cin >> a[i];
  9. ll ans = 0;
  10. for (int i = 1;i <= k;i++) {
  11. int mx = 0;
  12. for (int j = i;j <= n;j += k)
  13. mx = max(mx, a[j]);
  14. ans += mx;
  15. }
  16. cout << ans << '\n';
  17. return true;
  18. }
  19. int main() {
  20. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  21. int t = 1;
  22. cin >> t;
  23. while (t--) {
  24. if (!solve()) cout << -1 << '\n';
  25. }
  26. return 0;
  27. }

B

题解

知识点:构造。

注意到,必然会有人赢 \(0\) 次,有人会赢非 \(0\) 次,因此 \(x, y = 0\) 或者 \(x,y \neq 0\) 都是不存在的。

假设非 \(0\) 数为 \(x\) ,即赢的人都赢 \(x\) 次,其他人都直接输掉,因为共有 \(n-1\) 次机会,那么只有 \(x | n-1\) 时合法,其余情况不存在。

在合法的情况下,尝试构造。我们只需要确定第一场赢的人,然后每隔 \(x\) 场换个人即可。为了方便,我们确定 \(2\) 为第一场赢的人,这样我们对人的编号加 \(x\) 就是下一个人。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. bool solve() {
  5. int n, x, y;
  6. cin >> n >> x >> y;
  7. if (x && y || !x && !y) return false;
  8. if (x < y) swap(x, y);
  9. if ((n - 1) % x) return false;
  10. else {
  11. for (int i = 2;i <= n;i += x) {
  12. for (int j = 1;j <= x;j++)
  13. cout << i << ' ';
  14. }
  15. cout << '\n';
  16. }
  17. return true;
  18. }
  19. int main() {
  20. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  21. int t = 1;
  22. cin >> t;
  23. while (t--) {
  24. if (!solve()) cout << -1 << '\n';
  25. }
  26. return 0;
  27. }

C

题解

知识点:构造。

考虑通过 \(n-1\) 次操作使得序列元素全部相等。

注意到同奇同偶和为偶数使数字向左转移,否则为奇数使数字向右转移。

显然,可以通过第一个数字把右侧所有与之奇偶性不同的数字变成相等的,现在考虑与第一个数字奇偶性相同的数字相等。

因为同奇偶性,所以只能向左转移。考虑找到最后一个与第一个数字同奇偶性的数字,随后通过这个数字向左把同奇偶性的数字都变为相等,之后再执行上一步把不同奇偶性的数字变成相等的。

上述操作,每次都能增加一个与初始数字确定相等的数字,所以共操作 \(n-1\) 次。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. bool vis[100007];
  5. bool solve() {
  6. int n;
  7. cin >> n;
  8. int ls = 1;
  9. for (int i = 1, x;i <= n;i++) {
  10. cin >> x;
  11. vis[i] = x & 1;
  12. if (vis[1] == vis[i]) ls = i;
  13. }
  14. cout << n - 1 << '\n';
  15. for (int i = ls - 1;i >= 1;i--) {
  16. if (vis[i] == vis[1])
  17. cout << i << ' ' << ls << '\n';
  18. }
  19. for (int i = 2;i <= n;i++) {
  20. if (vis[1] != vis[i])
  21. cout << 1 << ' ' << i << '\n';
  22. }
  23. return true;
  24. }
  25. int main() {
  26. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  27. int t = 1;
  28. cin >> t;
  29. while (t--) {
  30. if (!solve()) cout << -1 << '\n';
  31. }
  32. return 0;
  33. }

D

题解

知识点:区间dp,贪心。

任何时候,如果需要修改的地方是奇数,则不存在解法,即 \(-1\) 情况。

简单版本,规定 \(x \geq y\) ,因此:

  1. 当需要修改的位置 \(cnt\geq 4\) 时,可以每次隔一个取,使花费永远是 \(y\) ,最终花费是 \(\dfrac{cnt}{2} \cdot y\) 。
  2. 当 \(cnt = 2\) 时,除了花费 \(x\) 直接消掉,还可以通过一个其他不相邻的位置中转,两次不相邻修改实现一次相邻修改,花费 \(2y\) ,因此总花费是 \(\min(x,2y)\) 。

困难版本,没有规定 \(x,y\) 关系,但 \(x \geq y\) 那部分可以直接用贪心结论解决,\(x < y\) 只能dp解决了,这里采用线性dp,其他dp也能做。

设 \(dp[i]\) 表示从 \(1\) 到 \(i\) 修改成一样的最小花费。

当 \(i\) 为偶数时,\(dp[i] = \min(dp[i - 2] + (v[i] - v[i - 1]) \cdot x, dp[i - 1] + y)\) :

  1. 修改了前 \(i-2\) 个位置的花费,加上链式 \(x\) 修改第 \(i-1\) 和 \(i\) 个的花费。
  2. 修改了前 \(i-1\) 个位置除了一个位置没修改(可能在任何位置,也即包括了在第 \(i-1\) 处)的花费,加上不相邻修改 \(y\) 的花费。

取最小值。其中前者修改不需要考虑 \(y\) ,因为后者包括了;后者不需要考虑 \(x\) 链式修改,可以证明不可能更优。

当 \(i\) 为奇数时,\(dp[i] = \min(dp[i - 2] + (v[i] - v[i - 1]) \cdot x, dp[i - 1])\) :

  1. 修改了前 \(i-2\) 个位置除了一个位置没修改的花费,加上链式 \(x\) 修改第 \(i-1\) 和 \(i\) 个的花费。
  2. 修改了前 \(i-1\) 个位置的花费,留下第 \(i\) 处没修改。

取最小值。其中前者修改不需要考虑 \(y\) 不相邻修改,因为前者如果使用 \(y\) 修改 \(i-1\) 和 \(i\),花费等价于 \(dp[i-1]\) 的情况之一,即 \(dp[i-2]+y \geq dp[i-1]\) ,后者更优在于保留了第 \(i\) 个位置而非更前的位置,对偶数情况有更好的影响。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. ll dp[5007];
  5. bool solve() {
  6. int n;
  7. ll x, y;
  8. string a, b;
  9. vector<int> v;
  10. cin >> n >> x >> y;
  11. cin >> a >> b;
  12. v.clear();
  13. for (int i = 0;i < n;i++) {
  14. if (a[i] != b[i]) v.push_back(i);
  15. }
  16. if (v.size() & 1) return false;
  17. if (!v.size()) {
  18. cout << 0 << '\n';
  19. return true;
  20. }
  21. if (x >= y) {
  22. if (v.size() == 2 && v.front() + 1 == v.back()) cout << min(x, 2 * y) << '\n';
  23. else cout << v.size() / 2LL * y << '\n';
  24. }
  25. else {
  26. dp[0] = 0;
  27. dp[1] = min((v[1] - v[0]) * x, y);
  28. for (int i = 2;i < v.size();i++) {
  29. if (i & 1) dp[i] = min(dp[i - 2] + (v[i] - v[i - 1]) * x, dp[i - 1] + y);
  30. else dp[i] = min(dp[i - 2] + (v[i] - v[i - 1]) * x, dp[i - 1]);
  31. }
  32. cout << dp[v.size() - 1] << '\n';
  33. }
  34. return true;
  35. }
  36. int main() {
  37. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  38. int t = 1;
  39. cin >> t;
  40. while (t--) {
  41. if (!solve()) cout << -1 << '\n';
  42. }
  43. return 0;
  44. }

E

题解

知识点:数学,线性dp。

显然,直接求第 \(t\) 秒 \((x,y)\) 是否有球非常困难,但是求 \([0,t]\) 秒内经过 \((x,y)\) 的数量(包括这个格子本身)是比较容易的。

每个位置都是方向右下交替进行,且初始是朝右。因此,假设 \([0,t]\) 秒内经过 \((i,j)\) 的球有 \(n\) 个,那么可以得知 \([0,t+1]\) 秒内经过 \((i+1,j)\) 的球有 \(\lceil \frac{n}{2} \rceil\) 个,经过 \((i,j+1)\) 的球有 \(\lfloor \frac{n}{2} \rfloor\) 个。

但是,在 \(t+1\) 秒及其之后到达 \((i,j)\) 的球不可能在 \([0,t+1]\) 秒内经过 \((i+1,j)\) 和 \((i,j+1)\) ,因为从 \((i,j)\) 到 \((i+1,j)\) 或 \((i,j+1)\) 需要 \(1\) 秒。因此,要求 \([0,t]\) 秒内经过 \((x,y)\) 的数量,则只需要 \([0,t-(i+j)]\) 秒内经过 \((i,j)\) 的数量。

我们知道 \([0,t]\) 内经过 \((0,0)\) 的球有 \(t+1\) 个。因此,能递推得出 \([0,t]\) 秒内经过 \((x,y)\) 的球的个数。。

设 \(dp[i][j]\) 是 \([0,t]\) 秒内 \((i,j)\) 经过了多少能到达 \((x,y)\) 的球的数量,初始条件是 \(dp[0][0] = \min(t - (x+y)+1,0)\) 。转移方程为:

  1. dp[i + 1][j] += dp[i][j] / 2;
  2. dp[i][j + 1] += dp[i][j] - dp[i + 1][j];

时间复杂度 \(O(q)\)

空间复杂度 \(O(1)\)

代码

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. ll get(ll t, int x, int y) {
  5. vector<vector<ll>> dp(x + 7, vector<ll>(y + 7));
  6. dp[0][0] = max(t - (x + y) + 1, 0LL);
  7. for (int i = 0;i <= x;i++) {
  8. for (int j = 0;j <= y;j++) {
  9. dp[i + 1][j] += dp[i][j] / 2;
  10. dp[i][j + 1] += dp[i][j] - dp[i + 1][j];
  11. }
  12. }
  13. return dp[x][y];
  14. }
  15. bool solve() {
  16. ll t;
  17. int x, y;
  18. cin >> t >> x >> y;
  19. cout << (get(t, x, y) - get(t - 1, x, y) ? "YES" : "NO") << '\n';
  20. return true;
  21. }
  22. int main() {
  23. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  24. int t = 1;
  25. cin >> t;
  26. while (t--) {
  27. if (!solve()) cout << -1 << '\n';
  28. }
  29. return 0;
  30. }

Codeforces Round #821 (Div. 2) A-E的更多相关文章

  1. Codeforces Round #821(Div.2) (A-C) 题解

    Codeforces Round #821(Div.2) (A-C) A.Consecutive Sum 大致题意 给定一组共 n 个数据 ,如果俩个数的下标在 mod k 意义下同余,则可以交换a[ ...

  2. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  3. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  4. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  5. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  6. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  7. Codeforces Round #262 (Div. 2) 1003

    Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...

  8. Codeforces Round #262 (Div. 2) 1004

    Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...

  9. Codeforces Round #371 (Div. 1)

    A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...

  10. Codeforces Round #268 (Div. 2) ABCD

    CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...

随机推荐

  1. VUEX 使用学习六 : modules

    转载请注明出处: 当Store中存放了非常多非常大的共享数据对象时,应用会变的非常的复杂,Store对象也会非常臃肿,所以Vuex提供了一个Module模块来分隔Store.通过对Vuex中的Stor ...

  2. spring--是如何解决单例模式下循环依赖问题的

    Spring 解决单例 bean 的循环依赖主要依赖于容器的三级缓存机制,以及 bean 的提前暴露.这里是它如何工作的: 三级缓存: 一级缓存(singletonObjects):存储已经经过完整生 ...

  3. Pycharm配置git

    原文链接:https://www.jianshu.com/p/ae92970d2062 1.下载Gitee插件 同样在设置页面,选中 Plugins,并搜索 Gitee安装. 安装后,重启一下Pych ...

  4. springboot封装统一返回

    springboot返回统一的标准格式 定义注解 package com.yaoling.annotation; import java.lang.annotation.*; @Target({Ele ...

  5. [转帖]一文读懂容器存储接口 CSI

    https://zhuanlan.zhihu.com/p/470093908 作者 | 惠志来源 | 阿里巴巴云原生公众号 导读:在<一文读懂 K8s 持久化存储流程>一文我们重点介绍了 ...

  6. [转帖]jmeter之发送jdbc请求--06篇

    1.setup线程组中新建一个JDBC Connection Configuration配置元件 2.设置配置信息 Database URL:jdbc:mysql://127.0.0.1:3306/v ...

  7. [转帖]Redash -- Redash部署安装docker版

    向导 官网 1.环境准备 1.1 安装docker和docker-compose 1.2 安装nodejs和npm 2.安装Redash 官网 主页 Developer Guide github 讨论 ...

  8. TCP内核参数与Nginx配置的简单测试

    背景 昨天晚上整理了下几个TCP内核的参数. 学习到了一点内核参数的影响. 但是因为时间比较晚了没有继续钻研与nginx的关系 今天想着继续研究一下TCP的部分参数与nginx的关系 每个系统都不一样 ...

  9. Linux执行SQLSERVER语句的简单方法

    背景 因为WTF的原因.经常有人让执行各种乱七八槽的删除语句 因为产品支持了10多种数据库. 这个工作量非常复杂. 为了简单起见,想着能够批量执行部分SQL. 其他的都处理过了,但是SQLSERVER ...

  10. NOI2023 游记

    不完全按时间顺序写.记录 NOI 的一些琐事. 从 XDFZ 坐大巴 5 个小时来到成七.第一眼看到的是一个放着 NOI 牌子的台阶,还有一个签名墙.好像在我们之前到的人不太多? 用中英双语签名(冷月 ...