CF909 题解

题目链接

A B C D E F

难度:红 黄 绿 蓝 绿 紫

题解

A

题目翻译:给定两个字符串,求字典序最小的“两字符串非空前缀拼接形成的字符串”。

算法标签:贪心

题目分析:

字典序最小,即从左往右依次比较字符,直到一方不剩字符或两字符不同。因此想到贪心。由于前缀非空,因此在前一字符串上不断输出,直到输出结束或字符大于后一字符串的第一个字符。

代码略。

B

题目翻译:

输入 \(n\),由此得到 \(\frac{n(n+1)}{2}\) 个线段。你可以将它们拼接在一起,但要注意不能改变它们的左右端点位置。求拼接形成的线段最小数量。下图为当 \(n=4\) 时的最优解。

算法标签:数学、构造、贪心

题目分析:本题有多种解题思路。

  1. 打标找规律(其一)

    若将答案按照 \(n(0 \le n)\) 的大小排成一个数列,则该数列的前几项为:

0, 1, 2, 4, 6, 9, …

不难发现答案为 \(\lfloor \frac{n+1}{2} \rfloor \times \lceil \frac{n+1}{2} \rceil\)。直接做就做完了。

#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
n++;
cout << floor(n / 2.0) * ceil(n / 2.0) << endl;
return 0;
}
  1. 打标找规律(其二)

    不难发现答案有规律 \(f_i=2\times f_{i-1}-2\times f_{i-3}+f_{i-4}\)。直接做就做完了。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
if (n == 1) puts("1");
else if (n == 2) puts("2");
else if (n == 3) puts("4");
else if (n == 4) puts("6");
else {
int a = 1, b = 2, c = 4, d = 6, e;
n -= 4;
while (n--) {
e = 2 * d - 2 * b + a;
a = b;
b = c;
c = d;
d = e;
}
printf("%d\n", d);
}
return 0;
}
  1. 对规律进行证明

    因为规律可能错误,为了避免罚时(CF 赛制)和挂分(OI 赛制),需要对规律进行证明。

    以下内容翻译自官方题解

考虑长度为 \(1\) 的段 \([i, i + 1]\)。显然,覆盖此段的所有段必须属于不同的层。为了覆盖它,线段的左端必须位于点 \(0, 1,…, i\)(共 \(n-i\) 种选择),而右端分别在点 \(i+1,i+2,…,n\)(共 \(n-i\) 种选择)。所以覆盖 \([i, i + 1]\) 的段数等于 \(m_i=(i + 1)(n - i)\)。在所有 \(i=0,…,n-1\) 中,\(m_i\) 的最大值给出了层数的下界。

由于该问题不需要显式构造,我们可以猜测这个界限是精确的。最大值 \(m_i\) 可以在 \(O(n)\) 内找到;或者,可以看出,当 \(n\) 为奇数时,最大值出现在中间段,而当 \(n\) 为偶数时,最大值出现在两个中间段之一。

所以答案是 \((\lfloor\frac{n}{2}\rfloor+1)\cdot\lceil\frac{n}{2}\rceil\)。

我们也可以通过一个明确的构造来证明这一点。将所有线段按照其左端点的非降序排列,然后再按照其右端点的升序排列。尝试贪心地为每个下一段找到一个位置:如果 \(i\) 是当前线段的左端点,且线段 \([i, i+1]\) 在某一层是空闲的,则将当前线段添加到该层;否则,用当前线段开始一个新的层。

是的,这就是个 \(O(1)\) 的问题!(滑稽)

C

题目翻译:

题目给定一段类 Python 代码(只有两种语句:p(代表print)和f(代表for)),要求计算出这段代码有多少种合法的缩进。答案对 \(10^9+7\) 取模。

算法标签:动态规划

题目分析:类 Python 语言的缩进规则如下:

  • 第一条语句不加缩进
  • 对于其他语句有:
    • 若其为某条 for 的循环体时,加该 for 语句缩进的下一级
    • 否则不缩进
  • 特别的,每条 for 都必须有至少一条语句作为循环体

    这是一个例子:
print
print
for
print
for
print
print
print
print

于是可以想到动态规划。设 \(dp_{i,j}\) 表示第 \(i\) 条语句缩进 \(j\) 级的方案数,\(s_i\) 表示第 \(i\) 条语句。

显然当 \(s_{i-1}=\text{"f"}\) 时,\(dp_{i,j}\) 只能从 \(dp_{i-1,j-1}\) 转移;而当 \(s_{i-1}=\text{"p"}\) 时,它可以从任意 \(dp_{i, k}(j \le k \le i)\) 处转移。因此可以维护后缀和加速。时间复杂度 \(O(n^2)\)。

#include <bits/stdc++.h>
using namespace std;
int dp[5010][5010], sum[5010], n, cnt = 0;
string s, lst;
const int mod = 1e9 + 7;
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> s;
lst = s;
dp[1][0] = 1;
for (int i = 2; i <= n; i++) {
cin >> s;
if (lst == "f") {
for (int j = 1; j <= i; j++) {
dp[i][j] = dp[i - 1][j - 1];
}
} else {
for (int j = i; j >= 0; j--) {
dp[i][j] = (dp[i][j + 1] + dp[i - 1][j]) % mod;
}
}
lst = s;
}
int ans = 0;
for (int i = 0; i <= n; i++) ans = (ans + dp[n][i]) % mod;
cout << ans << "\n";
return 0;
}

D

题目翻译:

给定一条直线上的一组点。每个点都有一个指定的颜色。对于点 \(a\),它的邻居是在它们和 \(a\) 之间没有其他点的点。每个点最多有两个邻居——一个在左边,一个在右边。

对这组点执行一系列操作。在一个操作中,你删除所有有至少一个不同颜色的相邻点的点。同时删除点,即首先决定要删除哪些点,然后删除它们。之后,您可以执行下一个操作等。如果操作不会删除任何点,则不能执行该操作。

您需要执行多少次操作,直到下一个操作没有任何要删除的点?

算法标签:优化暴力

题目分析:如果暴力删点,总复杂度 \(O(n^2)\) 无法接受。但我们不难发现字符串内最多只有 \(26\) 种字符,于是想到优化暴力。

考虑将字符相同的区间“缩点”。由于每次删除的是有一个不同颜色的相邻点的点,所以对于长度 \(\ge 2\) 的区间,每次操作会删除其最左侧和最右侧的点(如果其左、右存在相邻点)。因此,总复杂度会降到近似 \(O(n)\)。

注:下面的代码因为 CF 网络故障,暂时未确定是否能够通过本题。

#include <bits/stdc++.h>
using namespace std;
string s;
int a[1000010], cnt = 1;
char c[1000010];
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> s;
a[1] = 1; c[1] = s[0];
for (int i = 1; i < s.size(); i++) {
if (s[i] == s[i - 1]) {
a[cnt]++;
} else {
a[cnt + 1] = 1;
c[cnt + 1] = s[i];
cnt++;
}
}
int ans = 0;
while (cnt > 1) {
for (int i = 1; i <= cnt; i++) {
if (i == 1 || i == cnt) a[i]--;
else a[i] -= min(2, a[i]); // 当区间内点数不足时全部删除
}
int tmp = 0;
for (int i = 1; i <= cnt; i++) { // 去除不存在的区间 && 合并区间
if (a[i] == 0) continue;
if (c[i] == c[tmp]) c[tmp] += c[i];
else {
tmp++;
c[tmp] = c[i];
a[tmp] = a[i]; // copy
}
}
ans++;
cnt = tmp;
}
cout << ans << '\n';
return 0;
}

E

题目翻译:

算法标签:

题目分析:

F

题目翻译:

算法标签:

题目分析:

Codeforces 909 A-F的更多相关文章

  1. Codeforces #541 (Div2) - F. Asya And Kittens(并查集+链表)

    Problem   Codeforces #541 (Div2) - F. Asya And Kittens Time Limit: 2000 mSec Problem Description Inp ...

  2. Educational Codeforces Round 40 F. Runner's Problem

    Educational Codeforces Round 40 F. Runner's Problem 题意: 给一个$ 3 * m \(的矩阵,问从\)(2,1)$ 出发 走到 \((2,m)\) ...

  3. codeforces Gym 100187F F - Doomsday 区间覆盖贪心

    F. Doomsday Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/F ...

  4. Codeforces gym 100685 F. Flood bfs

    F. FloodTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100685/problem/F Desc ...

  5. Codeforces Gym 100513F F. Ilya Muromets 线段树

    F. Ilya Muromets Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513/probl ...

  6. Educational Codeforces Round 61 F 思维 + 区间dp

    https://codeforces.com/contest/1132/problem/F 思维 + 区间dp 题意 给一个长度为n的字符串(<=500),每次选择消去字符,连续相同的字符可以同 ...

  7. Educational Codeforces Round 51 F. The Shortest Statement(lca+最短路)

    https://codeforces.com/contest/1051/problem/F 题意 给一个带权联通无向图,n个点,m条边,q个询问,询问两点之间的最短路 其中 m-n<=20,1& ...

  8. Codeforces Gym 100513F F. Ilya Muromets 水题

    F. Ilya Muromets Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513/probl ...

  9. Educational Codeforces Round 12 F. Four Divisors 求小于x的素数个数(待解决)

    F. Four Divisors 题目连接: http://www.codeforces.com/contest/665/problem/F Description If an integer a i ...

  10. [codeforces/edu5]总结(F)

    链接:http://codeforces.com/contest/616 A题: 统一成1e6长度的字符串,右对齐比较字典序. B题: 求所有行的最小值,里面最大的那个.暴力. C题: 先用dfs给每 ...

随机推荐

  1. 【Azure Logic App】在逻辑应用中开启或关闭一个工作流是否会对其它工作流产生影响呢?

    问题描述 使用标准版的Azure Logic App服务,可以创建多个工作流(workflow),如果在启用/禁用其它的工作流时,是否会对正在运行其它工作流造成影响呢? 问题解答 在实际的测验中,我们 ...

  2. pyinstall通过配置.spec文件引用资源文件

    pyinstall通过配置.spec文件引用资源文件 pyinstall可以自动将所有依赖的.py文件连接起来编译成一个可执行exe文件,但是如果在程序中 使用了外部资源,如图片,或者是其它的配置文件 ...

  3. Homebrew 使用

    使用 brew install brew uninstall|remove|rm brew list # *显示已安装软件列表 brew upgrade # 更新 Homebrew brew sear ...

  4. Seata 核心源码详解

    参考文章: 分布式事务实战方案汇总 https://www.cnblogs.com/yizhiamumu/p/16625677.html 分布式事务原理及解决方案案例https://www.cnblo ...

  5. 游戏AI行为决策——MLP(多层感知机/人工神经网络)

    游戏AI行为决策(特别篇)--MLP(附代码与项目) 你一定听说过神经网络的大名,你有想过将它用于游戏AI的行为决策上吗?其实在(2010年发布的)<最高指挥官2>中就有应用了,今天请允许 ...

  6. 17 Python异常处理(捕获异常、抛出异常、自定义异常)

    本篇是 Python 系列教程第 17 篇,更多内容敬请访问我的 Python 合集 当我们编写代码时,可能会遇到各种各样的错误情况,比如除数为零.找不到文件.网络问题等等.为了优雅地处理这些问题,P ...

  7. PRCV 2023:语言模型与视觉生态如何协同?合合信息瞄准“多模态”技术

    PRCV 2023:语言模型与视觉生态如何协同?合合信息瞄准"多模态"技术 近期,2023年中国模式识别与计算机视觉大会(PRCV)在厦门成功举行.大会由中国计算机学会(CCF). ...

  8. ASP.NET Core Library – HtmlSanitizer

    介绍 要输出 Raw HTML 最好是先消毒一下. 使用 Library 就可以了. 参考 Github – mganss / HtmlSanitizer 安装 nuget dotnet add pa ...

  9. SVN(Linux)提交时强制写日志

    SVN(Linux)提交时强制写日志 1.创建并修改pre-commit文件 进入svn/code/hooks目录,在svn版本库的hooks文件夹下面,复制模版pre-commit.tmplcp p ...

  10. 2. 王道OS-操作系统的特征,发展和分类

    1. 并发:宏观上是同时发生的,微观是交替发生的 :ps:并行:宏观和微观都是同时发生的 : ps:单核CPU同一时刻只能执行一个程序,各个程序只能并发的执行 : 多核CPU同一时刻可以同时执行多个程 ...