比赛链接

A

题解

知识点:贪心。

代码

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

B

题解

知识点:贪心。

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using ll = long long;
  4. bool solve() {
  5. int a, b, c, d;
  6. cin >> a >> b >> c >> d;
  7. if (a == 0) {
  8. cout << min(b + c + d, 1) << '\n';
  9. return 1;
  10. }
  11. else {
  12. int ans = a + 2 * min(b, c) + min(a, abs(b - c) + d) + (abs(b - c) + d > a);
  13. cout << ans << '\n';
  14. }
  15. return true;
  16. }
  17. int main() {
  18. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  19. int t = 1;
  20. cin >> t;
  21. while (t--) {
  22. if (!solve()) cout << -1 << '\n';
  23. }
  24. return 0;
  25. }

C

题意

给一个长为 \(n\) 的排列,每次操作可以任选两个数,其中小的挪到开头,大的挪到末尾,问最少几次操作可以使得排列有序。

题解

知识点:贪心,枚举,双指针。

注意到,操作不影响没有被操作过的数字的相对位置,因此考虑排列中不需要操作的数字。显然,最终被保留的数字应该是连续上升的一个子序列,如 23456 是,而 13456 不是因为 \(1\) 和 \(3\) 中间没有 \(2\) 。

假设我们操作了某一组数 \((x,y)\) ,那么 \((x,y),(x-1,y+1),\cdots ,(1,n)\) 一定都需要操作一遍才能保证这些数字有序。因此只有中间的数我们不需要操作,所以我们保留的数字应该从中间开始往外拓展。

若 \(n\) 为奇数,则从中点 \(\dfrac{1+n}{2}\) 开始往两边扩展;若 \(n\) 为偶数,先保证 \(\left\lfloor \dfrac{1+n}{2} \right\rfloor ,\left\lceil \dfrac{1+n}{2} \right\rceil\) 有序,再从这两个数两边扩展,如果不有序直接输出 \(\dfrac{n}{2}\) 。

为了方便找到某个数的位置,我们可以先处理数到位置的映射 \(pos\) ,再利用双指针 \(l,r\) 指向扩展的边界,向两边同时扩展,如果有一边扩展不了那就不需要继续了,最后结果是 \(l-1\) 。

代码

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

D

题意

给你 \(n\) 个长为 \(m\) 的排列 \(a_i\) 。

定义一个排列 \(p\) 的值为满足 \(p_i = i,i \in[1,k]\) 中 \(k\) 的最大值。

定义两个排列 \(p,q\) 的乘法 \(p \cdot q\) 为 \(r_i = q_{p_i}\) 。

对于给定的 \(n\) 个排列中,对于每个排列 \(a_i\) 找到另一个排列 \(a_j\) ( \(j\) 可以等于 \(i\) )使得 \(a_i \cdot a_j\) 的值最大,求出这 \(n\) 个最大值。

题解

知识点:枚举。

先考虑两个排列 \(p,q\) 乘积的求值过程,即如何求出 \(q_{p_1} = 1,\cdots,q_{p_k} = k\) 中 \(k\) 最大值。

显然 \(q_{p_1} = 1\) ,即 \(q\) 中 \(1\) 的位置是 \(p_1\) ,我们就能得到 \(k\) 至少是 \(1\) ,以此类推直到 \(q_{p_i} \neq i\) 就能得到 \(k = i-1\) ,复杂度是 \(O(n^2m^2)\) ,先考虑先优化枚举过程。

既然我们要知道某个数的位置,那么我们可以先预处理出 \(q\) 所有数字出现的位置 \(pos\) 。我们发现 \(q_{p_i} = i\) 等价于 \(pos_i = p_i\) ,即 \(i\) 出现的位置等于 \(p_i\) 那么自然可以得到 \(q_{p_i} = i\) ,由此我们从 \(pos_1 = p_1\) 开始找到最大的 \(k\) 满足 \(pos_k = p_k\) 即可。现在复杂度是 \(O(n^2m)\) ,考虑优化 \(n\) 次查找。

我们发现查找的过程,其实就是一个 \(p\) 和 \(n\) 个 \(pos\) 匹配最长前缀的过程,可以用字典树 trie 解决,复杂度是 \(O(nm)\) 。但这里 \(m\) 不大(其实是我不会字典树),我们可以将排列用十进制压缩成一个整数,用 map 记录 \(n\) 个排列的前缀信息来解决。设 \(mp_i\) 为 \(n\) 个排列的 \(pos\) 前 \(i\) 个数的前缀信息,例如排列 \(pos = [3,1,4,2]\) 前三个数字的信息就是 \(314\) ,记录在 \(mp_3\) 中。例如,我们查找 \(p = [4,3,2,1]\) 前 \(2\) 个数的匹配信息时,只要判断 \(mp_2\) 中有无 \(43\) 即可。到此为止,我们对 \(p\) 从前 \(1\) 个数依次查找,最多查找 \(m\) 次就可以找到最大的 \(k\) 了,复杂度是 \(O(nm\log n)\) 。

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

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

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using ll = long long;
  4. int a[50007][11];
  5. int pos[11];
  6. map<ll, int> mp[11];
  7. bool solve() {
  8. int n, m;
  9. cin >> n >> m;
  10. for (int i = 1;i <= m;i++) mp[i].clear();
  11. for (int i = 1;i <= n;i++) {
  12. for (int j = 1;j <= m;j++) {
  13. cin >> a[i][j];
  14. pos[a[i][j]] = j;
  15. }
  16. ll _t = 0;
  17. for (int j = 1;j <= m;j++) {
  18. _t = _t * 10 + pos[j] - 1;
  19. mp[j][_t] = 1;
  20. }
  21. }
  22. for (int i = 1;i <= n;i++) {
  23. ll _t = 0;
  24. int ans = m;
  25. for (int j = 1;j <= m;j++) {
  26. _t = _t * 10 + a[i][j] - 1;
  27. if (!mp[j][_t]) {
  28. ans = j - 1;
  29. break;
  30. }
  31. }
  32. cout << ans << ' ';
  33. }
  34. cout << '\n';
  35. return true;
  36. }
  37. int main() {
  38. std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  39. int t = 1;
  40. cin >> t;
  41. while (t--) {
  42. if (!solve()) cout << -1 << '\n';
  43. }
  44. return 0;
  45. }

Educational Codeforces Round 142 (Rated for Div. 2) A-D的更多相关文章

  1. Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...

  2. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

  3. Educational Codeforces Round 43 (Rated for Div. 2)

    Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...

  4. Educational Codeforces Round 35 (Rated for Div. 2)

    Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...

  5. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...

  6. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...

  7. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  8. Educational Codeforces Round 39 (Rated for Div. 2) G

    Educational Codeforces Round 39 (Rated for Div. 2) G 题意: 给一个序列\(a_i(1 <= a_i <= 10^{9}),2 < ...

  9. Educational Codeforces Round 48 (Rated for Div. 2) CD题解

    Educational Codeforces Round 48 (Rated for Div. 2) C. Vasya And The Mushrooms 题目链接:https://codeforce ...

  10. Educational Codeforces Round 60 (Rated for Div. 2) 题解

    Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...

随机推荐

  1. html和php里引用文件

    html里引入css文件: <link href="base.css" rel="stylesheet" type="text/css" ...

  2. MyBatisPlus 常用知识点总结

    @ 目录 完整的Mybatis-Plus项目 常用注解 设置表名(@TableName) 设置实体类字段 (@TableField) 通过 @TableField(fill=FieldFill.INS ...

  3. windows中 mysql 免安装版安装

    基本安装 绝对路径中避免出现中文,推荐首选英文为命名条件! 以管理员身份打开命令行,并转到mysql的bin目录下 安装mysql服务 mysqld --install 若出现以下错误,需将缺失的文件 ...

  4. select中DISTINCT的应用-过滤表中重复数据

    在表中,一个列可能会包含多个重复值,有时也许希望仅仅列出不同(distinct)的值. DISTINCT 关键词用于返回唯一不同的值. SQL SELECT DISTINCT 语法 SELECT DI ...

  5. 关于Redis的,你了解多少?来看看我的笔记

    Redis 概述 Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据 ...

  6. 镜像制作工具diskimage-builder介绍

    简介 diskimage-builder(简称dib)是一款用于构建系统镜像的工具,它被设计用于OpenStack的TripleO项目,支持qocw2.vhd.raw等主流镜像格式. 在众多系统镜像构 ...

  7. 元数据Metadata到底有什么用

    什么是元数据 元数据Metadata很简单,是关于数据的数据.这就意味着是数据的描述和上下文.他有助于组织和发现理解数据. 举例: 1张照片中除了照片本身还是,照片的时间日期,大小,格式相机设置,地理 ...

  8. 云原生之旅 - 12)使用 Kaniko 在 Kubernetes上构建 Docker 容器镜像

    前言 前一篇文章[云原生之旅 - 11)基于 Kubernetes 动态伸缩 Jenkins Build Agents]有讲到在 Kubernetes Pod (Jenkins build agent ...

  9. bugku 计算器

    打开就一个输入框和验证,尝试后发现输入框限制了位数,这还不简单,F12直接修改表单长度试试 成功得到flag

  10. Mybatis-Plus通用枚举 -基于jackson(Springboot-web内置)

    枚举类 使用 @EnumValue注解标识数据库字段 package com.example.enumpackage; import com.baomidou.mybatisplus.annotati ...