4月模考
死亡回放 模考时间线
- 1:30 比赛开始,读
T1 宇宙爆炸的题 - 1:50 自己手模了几组样例,得出了一个错误结论,打出了第一版错误代码,然后上交( Wrong Answer 20 \color{red}\text{Wrong\ Answer\ 20} Wrong Answer 20)
- 中间拿了
T2 逃狱风云的部分分( Wrong Answer 10 \color{red}\text{Wrong\ Answer\ 10} Wrong Answer 10,最终分数),之后在想T3 奇怪物语,然后推出需要用到二进制,但是想不出来,交了一个暴搜(?( Time Limit Exceeded 20 \color{blue}\text{Time\ Limit\ Exceeded\ 20} Time Limit Exceeded 20) - 3:00 返回去检查
T1 宇宙爆炸正确性,发现果然有问题!迅速修改了一下,把栈改成队列,再交了一发( Wrong Answer 60 \color{red}\text{Wrong\ Answer\ 60} Wrong Answer 60) - 然后发现还是有问题!于是又改了改交了一发( Accepted 100 \color{green}\text{Accepted\ 100} Accepted 100)
- 可是我不自信啊!就把部分分改成了暴力,然后暴力挂了!( Wrong Answer 65 \color{red}\text{Wrong\ Answer\ 65} Wrong Answer 65,最终分数)
- 后面的时间要么在发呆,要么在狂想
T3 奇怪物语,中间好不容易意识到写个递推拿的分更多,但是 5 × 1 0 7 5\times 10^7 5×107 的空间复杂度我开成了long long( Time Limit Exceeded 0 \color{blue}\text{Time\ Limit\ Exceeded\ 0} Time Limit Exceeded 0,最终分数) T4 东部世界就没有去推了qwq
死因分析 错误点分析
- 应该多去拿每个题的部分分的,简单的式子都去推一下!
- 暴力也得去验证是否正确!
- 应该要意识到空间复杂度的影响!
- 题目中给的提示得最大化使用!
死亡证明 成绩

遗书 各题错误思路 & 正解
T1 宇宙爆炸
给定一个由等量的 0 0 0 和 1 1 1 组成的环 s s s,各有 n n n 个。对于每一个 1 1 1,如果其逆时针方向上第一个元素为 0 0 0,则它们会被一起删除,环会重新接上,这个过程一直重复直到不存在可以删除的元素。现在要求出一些位置,使得在这些位置插入一个 1 1 1 后,这个 1 1 1 不会被删除。
对于所有数据,保证: 1 ≤ n ≤ 1 0 6 1\le n\le 10^6 1≤n≤106, s i ∈ { 0 , 1 } s_i\in\{0,1\} si∈{ 0,1}。
错误思路
就不该加暴力!也不知道暴力哪错了……
正解
场上想的:遍历两遍环,开一个队列存当前这个环(不同起点),在队列里执行湮灭操作;在第二遍遍历的时候,如果发现将 x x x 加入队列后发生湮灭,且湮灭完了队列为空,则说明 x x x 后面一个元素是安全的。这很好想:如果某一时刻还剩下的元素没有被湮灭完,那么此时加入肯定会代替后面的某个元素进行湮灭操作。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
char s[maxn << 2]; int n;
int q[maxn << 3],ans[maxn << 1],tot; int l,r;
int main() {
freopen("bigbang.in","r",stdin);
freopen("bigbang.out","w",stdout);
scanf("%d%s",&n,s + 1);
n <<= 1;
for (int i = 1;i <= n;i ++)
s[i + n] = s[i];
l = 1,r = 0;
for (int i = 1;i <= (n << 1);i ++) {
while (l <= r && q[l] <= i - n) l ++;
if (l > r) {
q[++ r] = i; continue; }
if (s[q[r]] == '1' && s[i] == '0') {
r --;
if (l > r && i > n) ans[++ tot] = i - n;
} else q[++ r] = i;
}
sort(ans + 1,ans + tot + 1);
int x = unique(ans + 1,ans + tot + 1) - ans - 1;
for (int i = 1;i <= x;i ++) printf("%d%c",ans[i]," \n"[i == x]);
return 0;
}
T2 逃狱风云
各有 n n n 个犯人、盒子和纸条,编号均为 1 → n 1\to n 1→n。每张纸条随机放入不同的每个盒子里。每个犯人都需要按照一定策略在 n n n 个盒子中挑选 k k k 个打开,如果没有看见自己编号的纸条则所有人都将被处决。否则全员释放。求在最优策略下全员释放的概率。犯人与犯人之间无影响。
提示:最优策略为: i i i 号犯人先打开 i i i 号盒子,然后根据看到的纸条编号打开对应编号的盒子,直到 k k k 次用完或看到自己的纸条。
错误思路
压根不觉得这个提示是最优策略,以为只是针对于该样例而言可能的一个策略。然后就没有了,拿了 10 10 10 pts部分分。
正解
按照提示给定的策略,按照盒子与纸条的关系建一张图 G G G,如果 i i i 号盒子中放着 j j j 号纸条,则 i i i 像 j j j 连一条有向边。 G G G 中一共 n n n 个点、 n n n 条边,且每个点各有一条入边、出边。 G G G 一定由若干个互不相交的环组成。如果所有环的大小均不大于 k k k,那么所有犯人都能通过 k k k 步走到自己编号的点上。则题目转化为求 n ! n! n! 种图中所有环的大小都不大于 k k k 的概率。
令 f i f_i fi 表示 i i i 个点的图中,所有环大小均不大于 k k k 的张数, g i g_i gi 表示概率。显然 g i = f i i ! g_i=\cfrac{f_i}{i!} gi=i!fi,且对于 i ≤ k i\le k i≤k, f i = i ! , g i = 1 f_i=i!,g_i=1 fi=i!,gi=1。转移 f i f_i fi 时枚举包含第 i i i 个点的环的大小 j j j( j ≤ k j\le k j≤k),则这个环不包含 j j j 会有 A i − 1 j − 1 A^{j-1}_{i-1} Ai−1j−1 种形态,剩下 i − j i-j i−j 个点合法的方案数为 f i − j f_{i-j} fi−j,故转移方程为:
f i = ∑ j = 1 k A i − 1 j − 1 × f i − j = ∑ j = 1 k ( i − 1 ) ! ( i − j ) ! f i − j f_i=\sum^k_{j=1}A^{j-1}_{i-1}\times f_{i-j}=\sum^k_{j=1}\cfrac{(i-1)!}{(i-j)!}f_{i-j} fi=j=1∑kAi−1

本文是4月模考的复盘,记录了考试时间线、错误点分析和成绩。详细分析了T1 - T4各题的错误思路与正解,涉及环元素删除、犯人逃狱概率、操作得到指定数的方法数、连通图计数等问题,运用了队列、图论、矩阵优化等知识。
最低0.47元/天 解锁文章
705

被折叠的 条评论
为什么被折叠?



