USACO 2022 February contest

Cu

忘存代码了,看个乐就行。

T1 Sleeping in Class

给出 \(n\) 个数 \(a\),任意合并相邻两个数,问使合并到最后全部相等的合并次数最小值。

\(n\le 10^5,\sum a \le 10^6\)

因为合并到最后的数一定是 \(\sum a\) 的约数,所以枚举 \(\sum a\) 很少的约数然后 \(O(n)\) 判断即可。Orz huaruoji。

因为我没有注意到 \(\sum a\) 的范围,所以我直接暴力枚举第一个数合并到的位置,同样的判断。但加了个优化,如果答案比当前位置合并所花次数还小就 break。

\(O(n*玄学)\)。

T2 Photoshoot 2

给出两个排列,一次操作可以把第一个排列中的一个数任意左移,求最小操作次数把第一个排列变成第二个排列。

首先把第二个排列当做 \(12345\)。注意到一次操作只能左移,所以要把第一个排列的 \(5\) 归位,位置在 \(5\) 右边的数全都要动,我们发现因为这些数是任意动,所以它们一定可以在左边排好后依次插入,所以我们就只需要看左边的。这样有点像递归,但实际上,我们只需要从大到小枚举数的位置,维护之前最靠左的位置,如果新枚举到的在维护位置的右边就不用管了,把新枚举到的数与维护的位置中间的数计入操作次数并把当前位置作为新的最靠左的位置。

\(O(n)\) 即可。

T3 Blocks

随便dfs一下就行。

上一篇:函数指针


下一篇:带你读《C编程技巧:117个问题解决方案示例》之三:函数和数组