AtCoder Beginner Contest 279
C - RANDOM(排序+string)
存储下每个矩阵的列,排一个序,就可以判断是否全排列了。
参考代码:code
D - Freefall(知识内容:三分/求导+二分)
思路:
可以发现这是一个单峰函数,其函数图像如下:
既然是单峰,即可以三分来求解。不会三分可在此处学习
\(\rm int \ m1=\dfrac{l\times 2+r}{3},m2=\dfrac{l+r\times 2}{3};\)
\(\rm if \ (f(m1)>f(m2)) \ l=m1;\)
$\rm else \ r=m2; $
代码:code
F - BOX (并查集变式)
我们可以给每个盒子维护一个 \(box_i\),若 \(box_i=-1\) 表示这个盒子没有球,否则 \(box_i\) 表示的就是第一次放入这个盒子里的球,我们一开始可以这个第一个球为集合的根,即初始我们都有 \(box_i=i\)
然后我们在维护一个 \(id_x\) 表示以 \(x\) 这个球为第一个球的盒子是哪一个,初始也是有 \(id_i=i\)。
那么我们看操作 \(1\),相当于把盒子 \(y\) 合并到 \(x\) 里面,首先我们看 \(y\) 盒子是否有球,没球我们直接跳过即可,然后我们看 \(x\) 是否有球。如果没球,我们直接令 \(box_x=box_y,id[box[y]]=x\),否则我们就可以合并两个盒子的信息即我们做 \(merge(box[x],box[y])\) ,注意合并完之后,我们要 \(box[y]=-1\),表示当前盒子没有球了。
看操作 \(2\),跟操作一没什么区别,只是把盒子 \(y\) 改成了小球而已。
看操作 \(3\),直接找 \(x\) 的祖宗,看他的 id 即可。
参考代码:code
G - At Most 2 Colors
形式化题意: \(N\) 个格子,\(C\) 种颜料,现在要求给 \(N\) 个格子染色,要求任意连续 \(K\) 个格子最多染 \(2\) 种颜色,球求有多少种染法。
思路:
定义 \(dp_i\) 表示前 \(i\) 个格子的染色方案数。可以分为两种情况:
(1) \(i\) 之前 \(k-1\) 格(不包含 \(i\))只染一种颜色。
(2) \(i\) 之前 \(k-1\) 格(不包含 \(i\))只染两种颜色。
考虑每种情况,当前的决策 \(i\) 能染多少种颜色?显然的,(1) 能染 \(C\) 种,(2) 能染 \(2\) 种。
故 \(dp_i=(1)\times C+(2)\times 2\)。你笑了,这算什么式子。
从 \((1)\) 入手,因为 \(i\) 之前 \(k-1\) 格颜色都相同(只染一种颜色),那么可以直接转移到 \(dp[i-k+1]\)。
然而 \((2)\) 式并不好推算。但是我们知道:\((1)+(2)=dp[i-1]\)(仔细思考)
因为 \((1)=dp[i-k+1]\),那么 \((2)\) 自然等于 \(dp[i-1]-dp[i-k+1]\)。
故 \(dp_i=dp[i-k+1]\times C+(dp[i-1]-dp[i-k+1])\times 2\)。此题迎刃而解。
参考代码: code