Codeforces Round #545 (Div. 2) 题解
A. Sushi for Two
题意
在一个 01 序列中找出长为偶数的连续的一段使得它前一半和后一半内部分别相同,而前一半和后一半不同。
\(2\le n\le 100\ 000\)
题解
令共有 \(k\) 段连续的区间,第 \(i\) 段区间的长度设为 \(a_i\),则答案是在求 \(\max_{i=1}^{k-1}\min(a_i,a_{i+1})\)。我因为没好好判 \(\min\) 而轻松地丢掉了 WA on pretest 4 的50分。
代码
标签
- 枚举
B. Circus
题意
有 \(n\) 个人,需要把它们分成两组,每组恰好 \(\frac n2\) 个人。每个人可能会技能 \(1\) 或技能 \(2\),一个人可能会其中一种、两种都会或什么都不会。
要求第一组中会技能 \(1\) 的人数恰好等于第二组中会技能 \(2\) 的人数,输出方案。
\(2\le n\le 5\ 000\)
题解
\(O(n^2)\) 的做法其实有些冗余,所以找到一种好理解的 \(O(n)\) 算法。
我们用两个 0/1 来表示一个人会的技能。比如一个人会技能 \(1\) 而不会技能 \(2\) 则表示为 0 1。
由于 1 1 的限制比较大,而他在第一组或第二组都必须做出贡献,因此我们枚举 1 1 在第一组有 \(i\) 个,假定总共有 \(d\) 个 1 1,则钦定第二组有 \(k-i\) 个 1 1。
此时我们首先要把贡献较小的一边给补成 \(\max(i,d-i)\) 个,然后会分别剩下 \(a\) 个 0 0,\(b\) 个 0 1,\(c\) 个 1 0。
如果 \(b>c\),可以考虑把 \(b\) 多出来的 \(b-c\) 个塞给第一组,则不做出任何贡献。
同理如果 \(c>b\),可以考虑把 \(c\) 多出来的 \(c-b\) 个塞给第二组,则不做出任何贡献。
但是会有一种情况,导致 \(\max(i,d-i)+|b-c|>\frac n2\),此时就会有一些不得不做贡献的人,理解为溢出。此时就会产生一些不得不做的贡献,是无论如何都补不回来的。
因此,当 \(\max(i,d-i)+|b-c|\le \frac n2\) 时,就有解。我们首先把 \(i\) 个 1 1 输出,如果 \(i<d-i\),需要先用 1 0 把它补到 \(d-i\),这也是要输出的。然后剩下的优先选 0 1 输出,最后拿 0 0 补齐。
代码
标签
- 枚举
- 构造
C. Skyscrapers
题意
在 \(n\times m\) 的网格上,每个格子都有一个权值。现在对于每个格子 \((i,j)\),问给第 \(i\) 行和第 \(j\) 列重新赋值为正整数,使得它们的原相对大小不变,问最大的正整数最小是多少。
\(1\le n,m\le 1\ 000\)
题解
我们发现第 \(i\) 行和第 \(j\) 列仅在 \((i,j)\) 处产生联系,其余都是独立的。
因此对于所有元素,可以在 \(O(nm\log n)\) 的时间里知道它在那一行/那一列的排名,行和列、大的和小的都要照顾到。假设它在那一行里排名为 \(p\),那一列里排名为 \(q\),则答案为 \(\max(p,q)+\max(m-p,n-q)\)。
代码
标签
- 排序
- 贪心
D. Camp Schedule
题意
给定串 \(s\),代表学生的计划,其中 0 表示这一天没写作业,1 表示这一天写作业了。
给定串 \(t\),代表最佳计划,其中 0 表示这一天不用写作业,1 表示这一天要写作业。
你可以改变串 \(s\) 的顺序,最大化 \(t\) 在 \(s\) 中出现的次数。
\(1\le |s|,|t|\le 500\ 000\)
题解
可以看出给出 \(s\) 相当于给出了 \(0\) 和 \(1\) 的个数,因此我们需要考虑 \(t\) 的构造。我们发现 \(t\) 在 \(s\) 中的出现是可以重合的,因此我们求出 KMP 中的 \(nxt\) 数组,我们只取前 \(n-nxt[n]\) 个。假设前 \(n-nxt[n]\) 个字符构成的字符串为 \(u\),令 \(u\) 中 \(0\) 的个数为 \(p\),\(1\) 的个数为 \(q\);令 \(s\) 中 \(0\) 的个数为 \(a\),\(1\) 的个数为 \(b\),则至少能构成 \(\min\left(\left\lfloor\frac ap\right\rfloor,\left\lfloor\frac bq\right\rfloor\right)-1\) 个 \(t\) 。
把这些构造完后,我们还会剩下一些 \(0,1\),而且还有一个 \(t\) 是不完整的,我们尽量与 \(t\) 匹配地接在它后面。这样输出就可以了。
求 \(nxt\) 数组和构造时间复杂度为 \(O(\mathtt{strlen}(s))\)。
代码
标签
- KMP
- 构造
E. Museums Tour
题意
一周有 \(d\) 天。一个人在一周的第 \(1\) 天从 \(1\) 号点出发,城市的地图是一个 \(n\) 个点 \(m\) 条边的有向图。这个人每天晚上要么结束旅行,要么往某个方向行走一步。每个城市有一个博物馆,只在每周的特定时间开放。问他最多能参观多少个城市的博物馆。
\(1\le d\le 50\)
\(1\le n\le 100\ 000\)
\(1\le m\le 100\ 000\)
题解
好题。
我们考虑把每一天拆成 \(d\) 个点,令第 \(i\) 号点在第 \(j\) 天的点为 \([i,j]\)。存在 \(\left<i,v\right>\),则让 \([i,j]\) 向 \([v,j\bmod d+1]\) 连边。
注意:博物馆不开放仅代表不做出贡献,不代表那天不能去那个城市。因此连边不能省。
然后我们可以在这个有向无环图上跑 tarjan 缩点。
可以证明,在新的 DAG 上的任意一条链中,原图的每个点只会出现在一个强连通分量里。
- 在连边后的图上,如果原图中的点 \([i,j]\) 向 \([i,k]\) 有连边,那么 \([i,k]\) 一定向 \([i,j]\) 有连边。因此在路径上可能出现的原图同一个点的新点都会被缩到同一个强连通分量里。
因此我们可以计算每个 SCC 的贡献。当给出的矩阵中 \([i,j]\) 为 \(1\) 时则做出 \(1\) 的贡献,\(i\) 相同的不重复统计。
然后计算从 \([1,1]\) 开始的权值最长路。拓扑排序可以完成。
但是由于一共有 \(5\times 10^6\) 个点,递归可能会爆栈,因此我写的非递归(码量有点大但是不是很难写)。
可以参考 Pinkrabbit 的递归超小空间解法。
代码
标签
- tarjan
- 拓扑排序
F. Cooperative Game
题意
交互题
现在有 \(10\) 个棋子。有一个图,是由一条长为 \(t\) 个节点的链指向一个大小为 \(c\) 的有向环的。其中除了 home vertex的入度为 \(0\),finish vertex 的入度为 \(2\),其余各点的入度均为 \(1\);同时,所有点的出度都为 \(1\)。

现在,每一步你可以选取一些点让它走一步到它出边指向的点。走完每一步以后,交互器都会告诉你哪些棋子在同一个点上。现在要你在 \(3(t+c)\) 步以内,把所有的棋子都移动到 finish vertex。
\(1\le t,c,(t+c)\le 1\ 000\)
题解
由于之前做过的交互题都是和倍增/二进制有关,本题给出了 \(10\) 个点,而且 \(\log_2 1000\) 也恰好是 \(10\),于是就这样陷进去了…
实际上我们只需要 \(3\) 个点就能解决本题的问题,我们可以把这 \(10\) 个点分为 \(0,1,23456789\) 三个部分。
首先让 \(0\) 每走 \(2\) 步,\(1\) 走一步。当 \(0,1\) 相遇时环长即为 \(0\) 走过的距离减去 \(1\) 走过的距离。每次 \(0\) 总比 \(1\) 快一步。除了一种情况以外,环长也等于 \(1\) 走过的步数。这叫做Floyd判环。
一种情况:
如果下一步是 \(0,1\) 一起走的话,那么 \(0\) 走的步数就不恰好是 \(1\) 走的步数的两倍了,因此需要判一下。
此时我们知道 \(0,1\) 在环上的某个点相遇了。我们现在知道了环长 \(c\) 和链长 \(t\),但是我们不知道 finish vertex 在哪里。
我们为了让 \(01\) 与 \(23456789\) 在 finish vertex 相遇,我们可以构造出环上的一个点。设 \(1\) 号棋子已经走了 \(m\) 步,因此令 \(01\) 在环上“倒退 \(m\) 步”,也就是前进 \(-m\pmod c\) 步,此时就和 \(23456789\) 同步了。我们发现,环长一般情况下也恰好是 \(m\)(特殊情况是 \(m+1\),让 \(01\) 先走一步就可以了),然后让 \(0123456789\) 同时移动。
最终所有点相遇的地方就是 finish vertex 了。输出 done 即可。
一般情况下步数为 \(2(t+c)-1\),上面提到的情况步数为 \(2(t+c)\)。
代码
标签
- Floyd判环
- 交互
Codeforces Round #545 (Div. 2) 题解的更多相关文章
- Codeforces Round #545 (Div. 1) 简要题解
这里没有翻译 Codeforces Round #545 (Div. 1) T1 对于每行每列分别离散化,求出大于这个位置的数字的个数即可. # include <bits/stdc++.h&g ...
- Codeforces Round #182 (Div. 1)题解【ABCD】
Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...
- Codeforces Round #608 (Div. 2) 题解
目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...
- Codeforces Round #525 (Div. 2)题解
Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...
- Codeforces Round #528 (Div. 2)题解
Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...
- Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F
Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...
- Codeforces Round #677 (Div. 3) 题解
Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...
- Codeforces Round #665 (Div. 2) 题解
Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...
- Codeforces Round #160 (Div. 1) 题解【ABCD】
Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...
随机推荐
- Win 7 Windows Update无法自动更新解决方案
最近发现系统很长时间没有自动更新过了,手动更新后,提示返回错误码WindowsUpdate_8024402F.网络上搜索到的解决方法大多是删除更新临时目录,重启WINDOWS UPDATE服务,然而试 ...
- MyBatis 3(中文版) 第四章 使用注解配置SQL映射器
本章将涵盖以下话题: l 在映射器Mapper接口上使用注解 l 映射语句 @Insert,@Update,@Delete,@SeelctStatements l 结果映射 一对一映射 一对多映射 l ...
- HUST软工1501-1503班第4周作业成绩公布
说明 本次公布的成绩为第四周作业的结果: 第4周小组作业:WordCount优化 如果同学对作业结果存在异议,可以: 在毕博平台讨论区的第4周在线答疑区发帖申诉. 或直接在博客园本帖中进行评论进行申诉 ...
- [GO]无缓冲通道(unbuffered channel)
无缓冲通道(unbuffered channel)是指在接收前没有能力保存任何值的通道,在之前的例子中使用的都是无缓冲通道,需要注意的是,对于无缓冲通道而言,不管是往通道里写数据还是从通道里读数据,都 ...
- ubuntu 14.04常见问题
1. 改root密码 sudo passwd root 2. 显示登录框 sudo gedit /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf 添加 ...
- [LeetCode 题解]: Permutations
Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the follow ...
- Oracle觸發器調用procedure寄信
最近寫了一直Web Service給很多不同站的客戶端呼叫,并直接寄信通知程式中的異常. 直接在oracle中設置某張表的trigger(after insert),當有新的異常資料寫入時候,寄給相關 ...
- CF455C Civilization | luogu HXY造公园
题目链接: https://www.luogu.org/problemnew/show/P2195 http://codeforces.com/contest/455/problem/C 显然我们可以 ...
- “全栈2019”Java第七章:IntelliJ IDEA注释快捷键
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- [Swift]在Swift中实现自增(++)、自减(--)运算符:利用extension扩展Int类
自增(++).自减(--)运算符主要用在For循环中,Swift有自己更简易的循环遍历方法,而且类似x- ++x这种代码不易维护. Swift为了营造自己的编码风格,树立自己的代码精神体系,已经不支持 ...
