博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法设计 熄灯问题
阅读量:4980 次
发布时间:2019-06-12

本文共 2239 字,大约阅读时间需要 7 分钟。

题目描述:

  有一个由按钮组成的矩阵,其中每行有6个按钮,共5行。每个按钮的位置上有一盏灯。当按下一个按钮后,该按钮以及周围位置(上边、下边、左边、右边)的灯都会改变一次。即,如果灯原来是点亮的,就会被熄灭;如果灯原来是熄灭的,则会被点亮。在矩阵角上的按钮改变3盏灯的状态;在矩阵边上的按钮改变4盏灯的状态;其他的按钮改变5盏灯的状态。

  所以在5x6的矩阵中,左边矩阵中用X标记的按钮表示被按下,右边的矩阵表示灯状态的改变。对矩阵中的每盏灯设置一个初始状态。请你按按钮,直至每一盏等都熄灭。与一盏灯毗邻的多个按钮被按下时,一个操作会抵消另一次操作的结果。在下图中,第2行第3、5列的按钮都被按下,因此第2行、第4列的灯的状态就不改变。

  请你写一个程序,确定需要按下哪些按钮,恰好使得所有的灯都熄灭。根据上面的规则,我们知道

  1)第2次按下同一个按钮时,将抵消第1次按下时所产生的结果。因此,每个按钮最多只需要按下一次;

  2)各个按钮被按下的顺序对最终的结果没有影响;

  3)对第1行中每盏点亮的灯,按下第2行对应的按钮,就可以熄灭第1行的全部灯。如此重复下去,可以熄灭第1、2、3、4行的全部灯。同样,按下第1、2、3、4、5列的按钮,可以熄灭前5列的灯。

要求样例出入,输出所需的操作。

 

解题思路:

  为了方便,给每个灯的位置定一个坐标,得到一个5x6的数组,但是为了避免第一行,第一列最后一列需要额外的操作,我们讲数组设定为6x8的二维数组。

  puzzle[i][j]表示第i行第j列上灯的初试状态,1为亮,0为灭;

  press[i][j]表示要不要按下ij位置的灯,1为按下;

  如果这样的话有2的30次方种情况,太复杂,对算法进行优化,我们发现了规律

如果位置(1,j)的灯亮,则press[2][j]的值必为1;反之亦然,所有通过操作,将第一行的灯全部熄灭,而3,4,5行不受影响,继续后面的操作。

 

代码如下:

1 #include "stdio.h" 2  3 int puzzle[6][8]; 4 int press[6][8];  5  6 bool guess(){ 7     int i,j; 8          for(i=2;i<6;i++){ 9               for(j=1;j<7;j++){10                    press[i][j]=(press[i-1][j]+puzzle[i-1][j]+press[i-1][j-1]+press[i-2][j]+press[i-1][j+1])%2;11                   }12              }13          for(j=1;j<=6;j++){14             if(press[5][j]!=(puzzle[5][j]+press[5][j-1]+press[5][j+1]+press[4][j])%2)15                return false;16              }17          return true;18     }19 void process(){20     int c;21     for(c=1;c<7;c++)22         press[1][c]=0;23     while(!guess()){24         press[1][1]++;25         c=1;26         while(press[1][c]>1){27             press[1][c]=0;28             c++;29             press[1][c]++; 30           }31      }32 }33 34 int main(){35     int i=0,j=0;36     for(i=0;i<6;i++)37         puzzle[i][0]=puzzle[i][7]=press[i][0]=press[i][7]=0;38     for(j=0;j<8;j++)39         puzzle[0][j]=puzzle[5][j]=press[0][j]=press[5][j]=0;40         41     for(i=1;i<6;i++)42         for(j=1;j<7;j++)43         scanf("%d",&puzzle[i][j]); 44     45     process();    46     printf("press is:\n");47         48     for(i=1;i<6;i++){ 49         for(j=1;j<7;j++){ 50         printf("%d ",press[i][j]); 51         } 52         printf("\n");53     } 54 }

 

 

源码下载(百度云):链接: http://pan.baidu.com/s/1ntOqG7R 密码: ewij

转载于:https://www.cnblogs.com/SeekHit/p/4897669.html

你可能感兴趣的文章
optionMenu-普通菜单使用
查看>>
【MemSQL Start[c]UP 3.0 - Round 1 C】 Pie Rules
查看>>
Ognl中“%”、“#”、“$”详解
查看>>
我对应用软件——美团的看法
查看>>
python第六篇文件处理类型
查看>>
ubuntu16系统磁盘空间/dev/vda1占用满的问题
查看>>
grid网格布局
查看>>
JSP常用标签
查看>>
九涯的第一次
查看>>
处理器管理与进程调度
查看>>
向量非零元素个数_向量范数详解+代码实现
查看>>
java if 用法详解_Java编程中的条件判断之if语句的用法详解
查看>>
matlab sin函数 fft,matlab的fft函数的使用教程
查看>>
mysql sin() 函数
查看>>
单片机复位电路
查看>>
php json_decode失败,返回null
查看>>
3-day3-list-truple-map.py
查看>>
Edit控件显示多行文字
查看>>
JS第二周
查看>>
dataTable.NET的search box每輸入一個字母進行一次檢索的問題
查看>>