Pegged 即ural 1051
【Description】
Hades_Fei和他的MM都很喜欢一种叫做Pegged的游戏,这种游戏的中文名字叫做孔明棋(见KongMing_Chess.rar),但是MM觉得Hades_Fei的智商玩这种游戏太小意思了,所以她对这个游戏做了一下小小的改变,在一个无限大的棋盘的格子上有一些棋子,这些棋子构成一个M*N的矩形(M为高度,N为宽度)。请你求出最后最少能剩下几个棋子。
这可难倒了Hades_Fei,所以他需要Hzoiers的帮助…
注:孔明棋的游戏规则:你可以用一个棋子跳过另一个相邻的棋子,被跳过的棋子将被删除。
【Input Format】
本题有多组数据。对于每组数据,仅有一行,两个正整数M,N,最后一行M=N=0,无需处理此行数据。
【Output Format】
对于每组数据,一个正整数,表示最少剩下的棋子数。
【Sample Input】
3 4
0 0
【Sample Output】
2
【Data】
对于30%的数据 |
N,M≤10 |
Task≤2 |
对于60%的数据 |
N,M≤1000 |
Task≤10 |
对于100%的数据 |
N,M≤100000 |
Task≤100 |
这道题,就是一个找规律。
所谓找规律,就是这样。
【Pegged】
最简单的情况是N=1或者M=1的时候,答案肯定是 (n+M)div 2 。不管怎么跳,最后剩下的状态肯定是010101····。
当M=2的时候,N=2,3时分别剩下1个和2个。
M=3的时候,我们可以发现一个很牛逼的方案:
第一步将红色石子跳到1,吃掉3位置的石子,然后把2位子的石子跳到3,吃掉中间的那个石子,然后红色石子跳回到左上角,吃掉3位置的新石子。这样第二行的石子就被吃完了,而红色石子仍然在原来的位置。
也就是说,对于任意三个连续石子,如果它的边上有一个石子,那么这三个石子就能被吃完。
但是对于边界的三个石子则不一定能被消完。比如对于3×3的棋盘,先把第一行剩下一个,然后消第二行,最后把第三行消剩下一个,这样最后只能剩下两个。证明3*3只能剩下2个,可以顺便得出本题结论。
对棋盘内的格子进行染色(建立坐标)。a为(X+Y) mod 3=1的石子个数,b为余2的个数,c为余0的个数。那么每次跳石子,都会使a,b,c中两数减一,一数加一。也就是说这三个数的奇偶性是同步变化的。
当 N*M mod 3 = 0时,a=b=c,这时候反证之。如果最后能只剩下一个,那么a,b,c中必定有两数为0,一个为1,这与三个数的奇偶性矛盾。
进一步考虑 N*M mod 3 <> 0的情况,这时候初始情况必有一个数与其它两个数奇偶性不同,那么理论上可以达到0,0,1的状态。验证比较小的棋盘都最后得到了1个石子。那么就来证明它的成立。下面的证明是比较简单的了。
当(N > 2) and (M > 2)时,如果N*M mod 3 = 0,可证明一定能化成2*3的情况,也就是剩下两个。
如果N*M mod 3 <> 0,可证明一定能化到2*2或2*4或4*4的情况,也就是只剩一个。
上面的“可证明”,其实只是从边界开始吃石子。方案很好画,只是分类讨论烦了一点。
所以,这样代码就好说了。
var n,m:longint;
begin
assign(input,'Pegged.in');reset(input);
assign(output,'Pegged.out');rewrite(output);
read(n,m);
while(n<>0)and(m<>0)do
begin
if(n=1)or(m=1)then writeln((n+m)div 2)
else if((n*m)mod 3=0)then writeln(2)
else writeln(1);
readln(n,m);
end;
close(input);
close(output);
end.