NOIP2020 移球游戏
NOIP2020 移球游戏
前言
此题位于t3位置,并且是noip第一次考构造题和special judge。考场上由于不会t2觉得t3更简单,并且常年在cf上打比赛觉得构造题十分熟悉而写了t3放弃t2。但由于不会使用spj导致代码漏洞百出(事实上自己写这个题spj非常简单)最后混了10分。其实考场上想出的思路也只能得40分。还是太菜了呀!
题目
移球游戏
输入文件名:ball.in
输出文件名:ball.out
共 20 个测试点,每个测试点 5 分
每个测试点限时 1 秒,运行内存上限 512MB
小 C 正在玩一个移球游戏,他面前有 n + 1 根柱子,柱子从 1 ∼ n+1 编号,其中 1 号柱子、2 号柱子、…、n。n 号柱子上各有 m 个球,它们自底向上放置在柱子上,n+1 号柱子上初始时没有球。这 n×m 个球共有 n 种颜色,每种颜色的球各 m 个。
初始时一根柱子上的球可能是五颜六色的,而小 C 的任务是将所有同种颜色的球移到同一根柱子上,这是唯一的目标,而每种颜色的球最后放置在哪根柱子则没有限制。
小 C 可以通过若干次操作完成这个目标,一次操作能将一个球从一根柱子移到另一根柱子上。更具体地,将 xx 号柱子上的球移动到 y 号柱子上的要求为:
x 号柱子上至少有一个球;
y 号柱子上至多有 m−1m−1 个球;
只能将 x 号柱子最上方的球移到 y 号柱子的最上方。
小 C 的目标并不难完成,因此他决定给自己加加难度:在完成目标的基础上,使用的操作次数不能超过 820000。换句话说,小 C 需要使用至多 820000 次操作完成目标。
小 C 被难住了,但他相信难不倒你,请你给出一个操作方案完成小 C 的目标。合法的方案可能有多种,你只需要给出任意一种,题目保证一定存在一个合法方案。
输入格式
输入文件名为 ball.in。
第一行两个用空格分隔的整数 n,m。分别表示球的颜色数、每种颜色球的个数。 接下来 n 行每行 m 个用单个空格分隔的整数,第 i 行的整数按自底向上的顺序依次给出了 i 号柱子上的球的颜色。
输出格式
输出文件名为 ball.out。
本题采用自定义校验器(special judge)评测。 你的输出的第一行应该仅包含单个整数 kk,表示你的方案的操作次数。你应保证 0 \leq k \leq 8200000≤k≤820000。
接下来 k 行每行你应输出两个用单个空格分隔的正整数 x,y,表示这次操作将 x 号柱子最上方的球移动到 y 号柱子最上方。你应保证 1 \leq x, y \leq n + 11≤x,y≤n+1 且 x \neq yx
=y。
样例 1 输入
2 3
1 1 2
2 1 2
样例 1 输出
6
1 3
2 3
2 3
3 1
3 2
3 2
解法
40pts
每次将同种颜色的球移至一个柱子不断缩小问题。对于一个深度为\(m\)的球要想移到某个柱子只需要\(2m\)次(将他上方的m-1个球移走,将这个球移至一个柱子,将m-1个球移回来,再将这个球移至最终要放的目标柱)。平均下每个深度都有一个要移动的球,所以平均复杂度为\(O(nm^2)\)
code
1 | |
100pts
遇到这种题目正解一定要带一个log,只好往分治那方面想。所以可以把所有颜色一分两半,同类颜色在各自一半(并不要求同颜色连续)。
具体如何把颜色分类可用一个例子来说明。为方便描述,l表示左端点,r表示右端点,m表示中点这里用a表示要分类的柱子,b表示零时借用柱子,c表示空柱子。
- b–a中的球的个数–>c
- a–属于左边放b,否则放c–>b,c
- b,c–原来在a的–>a
- c–剩下的(原来是b的)–>b
现在我们有了r-l+1个相对有序的柱子,现在问题转化为如何将同色的一堆连续球放在一边。为方便表述z表示未完全分类的柱子左端点,同理y表示右端点。初始z=l,y=r
- 若zy上属于左边的多,则利用空柱子几次反转使左边颜色在zy顶上。总之要把少的颜色放在顶上。假设这时左边颜色少。
- z–左边颜色球–>c
- y–左边颜色球–>c
- z–剩下的且不超过y最大–y
- –y
- c---->z
这样y就缩小了,如此反复直至z==y-1==m
- f(l,m) f(m+1,r)
这样问题就解决啦,复杂度大概为\(mnlog^n\)
code
1 | |
NOIP2020 移球游戏
http://yoursite.com/2020/12/12/NOIP2020-移球游戏/