关灯游戏 Lights out (一)(极速求解)

来源:互联网 发布:c语言入门网站 编辑:程序博客网 时间:2024/04/29 07:09

关灯游戏(Lights Out)

      关灯游戏是Tiger Electronics在1995年发行的一款电子游戏,Parker Brothers在上世纪70年代发布过一款规则与此类似的3×3的游戏, Vulcan Electronics在1983年也生产过与此类似的游戏,名称为XL-25。

      目前这款游戏的中文名很混乱,网上可见“开关灯游戏”、“灭灯游戏”、“开灯游戏”、“熄灯游戏”、“点灯游戏”、“灯阵游戏”、“地板游戏”...虽然意思都差不多,但名称不统一,不利于学术研究和搜索。在维基百科里(https://en.wikipedia.org/wiki/Lights_Out_(game)),这款游戏的英文名称为:“Lights Out”,可翻译为“关灯游戏”。
      关灯游戏规则非常简单,在一个M×N阵列里,有若干盏灯亮着(可以全部都亮着),点击任意一盏灯(不管此灯是亮着还是灭着,都可以点),那么该灯以及与该灯相邻的上、下、左、右共五盏灯都同时会变成与自身相反状态,即亮的变灭,灭的变亮(由于边角的特殊性,点击边上的灯,只有四盏灯一起变化;点击角上的灯,只有三盏灯一起变化)。

      游戏的目标是:通过点击灯阵一些灯,使得灯阵上所有灯都熄灭。

      来看维基的一张游戏示意图:


      上图是一个5×5正方形灯阵,初始状态只有左上角一盏灯亮着;第一次点击右下角灯,则右下角三盏灯全部变亮;第二次点击右下角斜边第二个盏灯,结果如最后一个图所示(此时局面还有灯亮着,游戏并未结束)。

      关灯游戏规则虽然简单,但玩起来颇有难度。于是众多程序猿想到用计算机求解。常规解法是线性代数解法,这个有点数学含量。

      线性代数解法的优点很多,不单可以求解M×N任意阵列灯阵,而且对灯阵任意初始状态也能求解,是个不错的方法。不过,线性代数解法的缺点也是明显的,代码比较复杂,时间复杂度也降不下来,当灯数量很多时,就很难在有限时间内求解了。
      线性代数解法原理,网上已经有了,在这里就不介绍了。这里介绍笔者找到了一个速度超快的算法,求解511×511灯阵(初始状态全亮)耗时不到1秒,速度极快!算法很简单,就是只点击局面未亮的灯,一直找到解法为止。但笔者这个解法缺点也很明显,就是无法求解任意阵列关卡。

     代码如下(C/C++):

#include<stdio.h>  /*关灯游戏求解代码(只求解初始状态全亮灯阵)*/#define M 15       /*M等于灯阵行数*/#define N 31       /*N等于灯阵列数*/int main(void){/*M、N值须符合1, 2, 3, 5, 7, 11, 15, 23, 31, 47, 63, 95, 127, 191, 255, 383, 511...数列规律*/int a[M+2][N+2]={0},b[M+2][N+2]={0},i,j,k=1;while (k){for(i=0;++i<=M;)for(j=0;++j<=N;)if(!a[i][j])b[i][j]^=1,a[i][j]^=1,a[i][j+1]^=1,a[i][j-1]^=1,a[i+1][j]^=1,a[i-1][j]^=1;for(i=k=0;++i<=M;)for(j=0;++j<=N;)if(!a[i][j])k=1;}for(i=0;++i<=M;printf("\n"))for(j=0;++j<=N;)printf("%2d",b[i][j]);return 0;}

例如调整M=N=11,程序输出为:



      笔者这个解法只求解初始状态全都亮的灯阵,可以求解的正方形灯阵阶数为:

      1, 2, 3, 5, 7, 11, 15, 23, 31, 47, 63, 95, 127, 191, 255, 383, 511, 767, 1023, 1535, 2047, 3071, 4095, 6143, 8191, 12287...
      这个数列的通项公式为:a(2n) = 2*2^n - 1,a(2n+1) = 3*2^n - 1
      符合这个数列阶数的正方形灯阵,都可以求解,另外,4阶也可以求解。

      在“整数数列线上大全”(https://oeis.org/)网站上,这个数列编号为:A052955
      具体网址:

      https://oeis.org/search?q=7%2C11%2C15%2C23%2C31%2C47%2C63%2C95%2C127%2C191%2C255%2C383%2C511+&sort=number&language=&go=Search
      上面程序还可以求解一些矩形灯阵,对矩形的边有如下要求:
      1、当M等于1时,N值等于上面数列任意一个数值的矩阵均可求解;
      2、当M和N的关系为下面规律数值时,M×N矩阵均可求解:

M值137153163127255...N值37153163127255511...
      对上面程序点评:

      优点:程序简单,速度极快

       缺点:只能求解特殊规格矩阵,作用有限。       


0 0
原创粉丝点击