[zz]Flip and Shift -- POJ 1063 解题报告

 

详见:http://acm.pku.edu.cn/JudgeOnline/problem?id=1063

我试着自己翻译一下题意(意译式的):在日本有一种旋转寿司店,厨师把做好的寿司放到一个环形道上,而环形道在直在旋转,这样,围着环形道坐的顾客就能品味到不同的寿司。现在,假设在一个 L 个单位长的环形道上,每个单位长度放着一个或黑或白的盘子。环形道本身并不自己旋转,而是要靠一个机关来操作。这个机关固定在某个位置。它可以把它前面的三个连续的盘子反转位置,或者把环形道顺时针移动一个单位距离。例如,如果当前序列为 1 2 3 ... L,其中数字为盘子编号,而假定机关就在 3 号位置上,如果机关使用反转功能,则序列变成 1 4 3 2 5 ... L (注意黑体部分);如果使用了移动功能,则序列变成 L 1 2 3 4 ... L-1 ,现在摆在机关面前的是 2 号盘子。这里给盘子编号,是为了说明和举例,原题描述中并无编号。现在的问题是,给了一个盘子序列,要通过操作机关来把所有黑盘调整到一块,而所有白盘也在一块。但不是所有序列都能这么黑白两分的,比如序列 黑白黑白 就不能两分。写一个程序,接受一个盘子序列为输入,确定该序列是否可以黑白两分。

看问题要看本质。让我们先看看这个 turnstitle 到底能“真正”做些什么。连续的三个盘子,可能的情况是:1) ooo 2) xox 3)oxx 4)xxo 其中, x 和 o 表示不同颜色的盘子。除此之后,没有其它可能了。对于前两种情况,使用了 turnstitle 的 flip 功能和没使用是一样的,因此不起作用。那么,真正有用的就是后两者情况了。扳动了 turnstitle 的 flip 功能, 就把 3)变成 4),或者把 4) 变成 3)。本质上,就是把连续的两个 xx 向逆时针或顺时针方向前进一格,同时把在它们正前面的 o 抛到后面去。比如 3),本质上就 xx 向左(逆时针)移动了一格,然后把它们前面,即 xx 左边的那个 o 挪到 xx 的右边。而 4)的情况正好是左右互换。再结合 shift 功能,我们就可以把连续的两个 xx 向左或向右移动任意数量的格子!

基于以上本质上的观察,要把黑的和白的分开,那么,我们从 track 的任一处开始,把所有连续的两个 xx 移动到一起,如果最后的结果是 xxx... ooo... 则成功了,否则,序列不可以被黑白两分。例如 oxoxox 这些类型的序列,就不能黑白两分的。事实上,可以发展一些严格的数学定义来说明,只有这一类型的序列不能黑白两分,其它不能两分的都能转成这种类型的(同构)。简单地说,就是对于 xx,我们可以把它们从序列中删掉,而不影响序列的可分性。删除这些 xx 之后,序列要么为空,要么为 o,要么 ox,要么为 oxox...ox。前两者即为可分,后者显然不可分。当我们写程序时,实际碰到的还有另一种情况,即 oxox...oxo (长度为奇数,且 o 和 x 交替着出现)。事实上,它就是 o,因为 track 是环状的,它可以通过继续删除 xx 这种组合,从而最后变成 o 类型。

这样,我们只需要从头开始扫描一遍序列,如果当前的盘子和前一个盘子颜色相同,则删除掉当前盘子和前一个盘子,否则,当前的序列长度增加 1。当序列扫描结束时,如果序列的长度不大于 2 或长度为奇数,则可分,否则,不可分。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值