官网地址
CF地址
补题,(和重做差不多了😂)
B - Connect3
题意
给出一个 4×4 的网格图,有两个玩家轮流下黑棋和白棋,每次下棋位置必须保证该棋子的下方有一个棋子,也就是堆栈,形式化地说就是,若下在 (i,j) 处,当且仅当, (i−1,j) 处必须有棋子。
若一个玩家获胜,规则类似于五子棋,只是将“五子”改成了“三子”,横着或竖着或斜着有三个同种颜色连着,执改棋玩家获胜。
黑棋先下,告诉你第一次下棋的位置和最后一个白棋下的位置,求最终一共有多少种棋盘(也就是不考虑过程,只考虑终态)。
思路
直接暴力模拟两个人的下棋顺序即可,总复杂度 O(152⋅16⋅3)=106。
注: 判断胜利的方法和最终棋盘的状态(可以使用set<vector<vector<int>> > st
)。
点击显/隐代码
E - How Many to Be Happy?
题意
给出一个含有N个节点M条边的带权值的无向图,对于其中的每一条边 e,定义 H(e) 为将其加入到最小生成树中所需要删除掉的最少的边数。
求 ∑e∈EH(e),E 为原图中的边集合。
N⩽100,M⩽500
思路
考虑 Kruskal 算法过程,如果边 e 要加入到最小生成树中,那么它所对应的两个端点必须不在同一集合中,于是问题转换为求解最小去掉多少边,从而将两个端点分离开,这就是标准的最小割,最小割转最大流就行了。
注: 之前在图中的边一定是val值小于当前边,容量都为1的双向边。
点击显/隐代码
F - Philosopher’s Walk
题意
给出一个 N×N 的图(类似于分形?), N=2k(k⩽15),图形是上一个图形通过对称和平移操作得到的,给出从起点 (1,1) 出发的步数,求最后到达的位置。
思路
考试时好像写了半天,没有抓住题目的关键,就是图形的变换规律,将该图形分为四个区域:
- 左下是上一个图形关于x=y对称
- 左上是向上平移 N/2 得到
- 右上是向右上平移 N/2 得到
- 右下是先关于y=n/2-x对称后,再向右平移 N/2 个单位后得到
使用递归即可,总复杂度 O(K)。
点击显/隐代码
H - Rock Paper Scissors
题意
两个人玩石头剪刀布,给定对方的序列S和自己的序列T,将自己的序列放在S序列中的某处,使得自己能胜利最多,求最多胜利多少场?
##思路
对于三种获胜方式,也就是石头胜剪刀,剪刀胜布,布胜石头,分三类讨论,每次将自己序列胜利的设置为1其他为0,对方序列胜利的设置为1其他位0,于是做一次卷积即可求出每个位置,自己该状态获胜个数,最后三者求和,取最大值即可。
设 A 为模式串长度为 m,B 为文本串长度为 n,A(x) 表示取出 A 串中第 x 个字符,设 D(i)=A(m−i−1),则考虑一下函数:
f(x)=i=0∑m−1A(i)B(x−m+1+i)=i=0∑m−1D(m−i−1)B(x−m+1+i)=i=0∑m−1D(i)B(x−i)
由于只有 1⋅1=1 所以就能判断每个位置有多少该条件能获胜了。
时间复杂度 O(3(n+m)log(n+m))。
点击显/隐代码
I - Slot Machines
题意
给出 n 个数字,你可以确定周期的开始位置 k,和从当前开始位置的周期 p 使得原序列满足该条件(注:不要求最后一段完整),求 k+p 的最小值。
思路
对kmp算法的精妙应用。
kmp算法是可以求出最小周期的,这道题如果能判断每个位置的最小周期,其实就能解决。
考虑将该数字序列反转,我们知道kmp可以求出当前后缀匹配的最长前缀长度,叫做border,假定当前位置为 i,当前位置的最长后缀记为 border,那么称 i−border 就是满足上述条件的最小周期。
下面证明一下这个问题:
图一中,蓝色部分和红色部分字符串完全相同,那么我们称绿色部分就是当前位置 i 向左的最小周期。
关键!图二中,可以看出绿色部分在蓝色部分中所占位置用紫色标出,那么由于蓝色和红色部分完全相等,那么该紫色部分就可以传递到红色部分上面。
于是以此类推,得出图三,紫色和绿色部分就是周期串,可以发现最左侧还差一点没有填满,那么它是什么呢?
用棕色标出来最后一段未填满部分,由于它在红色部分,又由于红色和蓝色相同,于是可以转移到蓝色上面,再对称下来,就正好是周期部分的一个前缀,这样最后一段就相当于是一个周期的前部分。
于是这样的周期就正好能够满足题意了。真的妙(
推广:如果我们要判断是否存在一个周期能完全填满以 i 结束的前缀,
那么只需要保证 imod(i−border)=0 就行了,这样就不存在最后棕色的那一小段了。
对于这道题,只需要将原串反过来,跑一次kmp,将每个位置的最优值求出来取 min 就行了。
时间复杂度 O(n)。
点击显/隐代码
K - Untangling Chain
题意
一个顶点再一个网格图上移动,一共移动 N 步,给定每次移动的方向,请你确定每个方向上的移动距离,使得最终的移动路径不会有交点。
N⩽104
思路
维护一个当前最小矩形覆盖,也就是可以通过这个矩形覆盖当前走过的所有路径,然后每次移动只要都恰好移动出该矩形,即可保证下一次转向的方向上,除了当前顶点外,没有其他路径。
总复杂度 O(N)
点击显/隐代码