华容道是什么意思,三国~华容道~是什么意思(12)


在解华容道的问题上,我觉得有两个问题比较棘手 。
其一、算法的效率 。
其二、获得最优解法 。
我是这样解决的:
1、 要提高算法的效率 , 首先要知道算法的瓶颈在什么地方,在得出每一个状态(走完一步各个棋子的位置)都要和前面的状态进行比较,以保证不重复,随着步数的增多,状态数会大幅度增加,这是,和前面的状态比较这一过程成了整个算法的效率 。解决的办法,从两个地方着手,其一,增加每一步比较的速度 。在程序中 , 用5*4的数组表示一个状态,这样,每一次比较要比较二十个数,因为数组中每个数定义从0-7,用三个二进制位可以表示,3*20=60位,用一个64位数就可以表示(有的资料说用四个字节就可以,我实在想不出来),这样每次比较一个64位数就可以了 。其二、减少比较的状态,这是提高效率的关键 。比较的时候不要和前面所有的状态都进行比较 , 只要和前两步的所有状态进行比较就可以了 。经过以上的优化,在解横刀立马时 , 大约需要一,两秒钟就可以了,(我的机器,赛扬1.1OC1.46) 。
2、 获得最优解法,比如横刀立马是81步,这里的一步指移动一个棋子,可以把一个卒子向一个方向移动两格,或者卒子拐弯移动两格,或者一个将向一个方向移动两格(横将横着移,竖将竖着移)都是一步 。获得最优解法的关键是把下一步可能有的走法全部算出来,不能遗漏 。我是根据空格来算走法的的,分三种情况:
① 、卒子拐弯移动,如果有连着两个空格(横向的) , 则如果在它的上面或下面(有四个位置)有卒子的话,那么可以拐弯移动,有四种走法 。如果两个空格是竖向的,那么,空格的左右如果有卒子 , 也可以拐弯移动,也有四种走法 。
②、向一个方向移动两格,这里可能出现的情况有:卒子向一个方向移动两格,横将横着移两格 , 竖将竖着移两格
③、考虑向一个方向移动一格的情况,这里情况很多 , 我不一一列举了 。
以上的算法很麻烦 , 很大一部分程序用来写这个了,如果大家有更简单的 , 可以告诉我,但一个原则,必须把所有的走法全部考虑 。
另外,说一下我在写程序时的小插曲 。程序快写好时,运行时发现,每解一次,内存使用会增加7,8兆,后来发现分配的内存每释放导致的,其实在函数中也就分配了几十个字节,由于被重复调用,最后泄漏的内存就很可观了,以后使用指针分配内存可要注意了,(C用malloc,C++用new) , 一定要释放,弄不好,^@^ 。
程序用dev-C++ 4.9.9.0(可以从网上下,只有十多兆)编译通过,因为dev C++没有框架等东西,所以界面直接用window API写的 。生成的可执行文件很?。?8 K 。另外 , 在程序中可以自定义布局 , 用5*4数表示 。其中0-空格,1-卒子,2到6 将,7曹操 。