zoukankan      html  css  js  c++  java
  • HDU 1564 + 证明

    题意:一个n*n的棋盘,一开始的时候棋子在一个角落的格子里,每次可以移动棋子到上下左右的相邻格子中(不能超过边界,而且不能走走过的格子);当不能走时,败。现在8600先走,问最后谁赢。

    题目分析:

      想了几个小时,然后没有打表,所以去搜了解题报告。

      最后的结论很简洁,所以先列出结论吧:

        该结论基于一个前提:还没走过的格子数为奇数时,先手胜。

        所以:

          n为偶数时,除去开局时棋子自己占的一格,余下n*n-1格,为奇数,先手胜。

          同理,n为奇数时,后手胜。

      以上。

     

      由于在下(有时候)有点固执,所以很多东西并不想只知道结论,而想知道为什么。所以我搜了很多份解题报告,却发现很多的解题报告都只说“打表出来的规律”。

     

      为了避免我之后自己说的证明方式有错,所以我先列出一些其他的说法。

      1、http://blog.csdn.net/topc0o0der/article/details/5928391  额……反正我看到“(1,1)(1,0)(1,1)(1,0)(1,1)  1,2,3,4,5”没看懂,然后就弃了……谁看懂了,务必解释解释……

     

      2、http://blog.csdn.net/shiyuankongbu/article/details/11294365 额……由于能力有限,完全没有理解作者在讲什么,总觉得描述和这道题不是很大关系的样子……

     

      3、http://www.cnblogs.com/kuangbin/archive/2013/07/22/3204654.html  这篇有图,所以比较好懂,但是我觉得这个证明方式不太对。简单说一下为什么吧。

      博主企图通过证明“如果初始棋盘(除了棋子的位置之外的部分)能被2*1的砖块不重复覆盖,就可以找到必胜策略”——这样的话“如果n为偶数,那么所有格子可以被2*1的砖块覆盖掉。这样先手每次都移动到当前1*2的另外一块。先手必赢。”

      我倒是觉得kuangbin举的那个例子不是很有说服力——为什么一定是那样覆盖的?如果是被“2*1的砖块不重复覆盖”,那么有很多种覆盖情况,可能不是每种情况都符合要求的吧,怎样的覆盖才能达到要求。所以我觉得要用这个方法证明这个问题,要企图证明的要点不是“能被2*1的砖块不重复覆盖,就可以找到必胜策略”,而是“存在一种不重复覆盖能找到必胜策略”。

      当然也许是我想少了……

     

      4、以上是我看的几份不是“打表出来的规律”的报告。

      然后我说说自己的证明吧,说的不对的地方,请大家务必指出啊,求轻喷……

     

      首先我的证明基于一个事实:1个奇数总能分成1个奇数和1个偶数之和;1个偶数只能分成2个奇数或者2个偶数。

     

      先来看看n=4时的情况:

      不妨设最右下角的位置为开局时棋子所在的位置。

      那么如图1,灰色的部分为先手可以走的格子,白色的部分为后手可以走的格子。

      (PS:就像国际象棋中的黑格象只会走到黑格中,白格象只会走到白格中。

          那么本题为什么是这样?是因为规则规定每次只能向外走一步而且只能上下左右走。

          所以一旦起点定下来,第一步是先手走,走到灰色格子,以后奇数的步数都是先手。

          所以离起点曼哈顿距离是奇数的都是先手走的。)

     

      

        图1

     

    我们来看一个走的实例:

      

        图2

     

    图2是一个先手赢的结局,通过这个例子可以发现如果这根时间线最后的终点是灰色就是先手胜(废话!先手下完,然后后手不能下了游戏就结束了,这不就是题目的要求么!)。

     

    那么由于一开始走的时候就是先手,所以时间线的起点是灰色(如图3)。

      图3(红色为时间线)( 名字好像有点中二啊……)

     

    如果要出现N(后手输)的结果,时间线最后也要是以灰色结尾。

     

    这说明什么?

    要知道这是一个灰色白色交替的时间线!

    所以这就意味着时间线的长度是奇数(以第一个灰色为起点,连接了多少个点长度就是多少,图2的长度为15)!

     

    由于起点一定是灰色,所以当n*n-1(n为偶数时)为奇数的时候,事实上是最长的那个时间线为奇数——如果按这个时间线走一定是先手胜。

    但是这样还是没有说为什么一定会赢啊!

    于是我们的前提可以派上用场了,1个奇数总能分成1个奇数和1个偶数之和。

     

    对方才不会那么蠢,走我们安排的最长路线,但是“1个奇数总能分成1个奇数和1个偶数之和”也就是说,把这条路线长度分割,一定能找到比这条路线短的另一个奇数路线,因为我们是先手,所以我们控制走分出来的奇数的路,而不是引向偶数的路。

     

    由于n是偶数,我们又是先手,每次都是先手面临时间线是奇数的情况,所以一定能赢。

    而如果n是奇数,那么最长路是偶数,我们走后就变成以白格为首的奇数长度了,然后每次都是后手面临时间线是奇数的情况,所以先手就输了。

     

    以上就是我的证明了,至于代码就很简单的判断奇偶,就不贴了。我觉得没什么太大的纰漏吧。囧(+﹏+)

  • 相关阅读:
    解析3D打印切片软件:Cura
    步步为营,打造CQUI UI框架
    PHP为什么empty可以访问不存在的索引
    这是一篇关于魔法(Science)上网的教程
    【新阁教育】这样玩PLC,是不是有意思多了
    「新阁教育」西门子TIA实现BadApple完整实例
    C#数据结构-赫夫曼树
    C#数据结构-线索化二叉树
    SQL优化器-RBO与CBO分别是什么
    Linux下安装并配置VSCode(Visual Studio Code)
  • 原文地址:https://www.cnblogs.com/PeanutPrince/p/3524628.html
Copyright © 2011-2022 走看看