解题报告 URAL 1051

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.

原文地址:https://www.cnblogs.com/SueMiller/p/2228591.html