这是枚举算法应用的一个例子,该问题理解起来不算复杂。具体的问题我简单的贴一个图:

这里我贴上代码,配有简单的注释,但是这个问题我一直在纠结是不是关灯的方式是有且仅有一个解,于是做了一个小小的测试,令人惊讶的是确实每次都恰好有一个解,网上好像大部分没有给出具体的数学证明,这里我抛砖引玉一下。先附上POJ已经AC的代码:

#include<iostream>
using namespace std;//这里首先把press和puzzle都做一个padding的操作,为了防止越界,5*6变成6*8
//这是检验press的第一行能否完成熄灯任务的函数
bool guess(int puzzle[][8], int press[][8])
{
// row, colint r, c; for (r = 1; r < 5; r++){for (c = 1; c < 7; c++)
//从枚举的press第一行中选取后,press的第二行知道第五行都是确定的,因为为了关闭上一行所有的灯只有唯一的方法,注意写的第x行是没有考虑padding的,不然手动加一,☺️press[r + 1][c] = (press[r][c] + press[r - 1][c] + press[r][c - 1] + press[r][c + 1] + puzzle[r][c]) % 2;}
//这里判断按照这样的情况能否把第五行关闭for (c = 1; c < 7; c++){if (puzzle[5][c] != (press[5][c] + press[5][c - 1] + press[5][c+1] + press[4][c]) % 2)return false;}return true;
}//枚举press的第一行的所有情况,运用位操作比6次循环要节省时间复杂度
void enumerate(int puzzle[][8], int press[][8])
{int c;for (c = 1; c < 7; c++)press[1][c] = 0;while (guess(puzzle, press) == false){press[1][1]++;for(c = 1; c < 6; c++){// press[1][1]++;if (press[1][c] > 1){press[1][c] = 0;press[1][c+1]++;}}}return;
}int main()
{int puzzle[6][8], press[6][8];//row, colint r, c, cases; //zero pad (1,1) (1,0)  pressfor (c = 0; c < 8; c++){press[0][c] = 0;}for(r = 0; r < 6; r++){press[r][0] = 0;press[r][7] = 0;}cin >> cases;for(int i = 0; i < cases; i++){for (int r = 1; r < 6; r++){for (int c = 1; c < 7; c++){cin >> puzzle[r][c];}}
//这里在不同的编译器可能会遇到问题,在OJ平台上第一天通过了,但是第二天又没通过,主要是输出格式的问题,结果是可以的enumerate(puzzle, press);cout << "PUZZLE #" << i+1 << endl;for (int r = 1; r < 6; r++){for (int c = 1; c < 7; c++){cout << press[r][c] << " ";}cout << endl;}}return 0;
}

好了接下来我把代码稍微改一下,为了显示每一种情况下究竟有多少种可能的结果,我试了一些都是1,我比较较真,所以想从数学上证明这个结论:

#include <iostream>
using namespace std;// function to judge whether the choosen press array can turn off the light
//press array, puzzle array
bool guess(int puzzle[][8], int press[][8])
{int i, j;for (i = 1; i < 5; i++){for (j = 1; j < 7; j++)press[i+1][j] = (puzzle[i][j] + press[i][j] + press[i - 1][j] + press[i][j - 1] + press[i][j + 1]) % 2;}for (j = 1; j < 7; j++)if (puzzle[5][j] != (press[5][j - 1] + press[5][j + 1] + press[5][j] + press[4][j]) % 2)return false;return true;
}//function to enumerate all the possibility of press col 1
int enumerate(int puzzle[][8], int press[][8])
{int i, j;int n = 64;
//这里total是关键,就是能够完成熄灯的所有可能方法数int total = 64;for (j = 1; j < 7; j++)press[1][j] = 0;while(--n) {if(guess(puzzle, press) == false) {total--;press[1][1]++;for (i = 1; i < 6; i++)if (press[1][i] > 1) {press[1][i] = 0;press[1][i + 1]++;}}press[1][1]++;for (i = 1; i < 6; i++)if (press[1][i] > 1) {press[1][i] = 0;press[1][i + 1]++;}}return total;
}int main()
{int c, r; //col rowint press[6][8], puzzle[6][8];int cases;cin >> cases;for(c = 0; c < 8; c++){press[0][c] = 0;}for (r = 0; r < 6; r++){press[r][0] = press[r][7] = 0;}// input the puzzle matrixfor (int j = 0; j < cases; j++){for (r = 1; r < 6; r++){for (c = 1; c < 7; c++){cin >> puzzle[r][c];}}cout << endl;cout << enumerate(puzzle, press) << endl;return 0;
}

我猜大家都会得到1的结果,那么究竟是为什么呢???

对于任意的puzzle矩阵puzzle[6][8],他的第一行在遇到了press[6][8]的第一行,会映射成一个不同的状态(64种状态之一),然后第一行确定了之后,第二行的press矩阵就定下来了,因为要完全关闭第一行的灯,即把puzzle的第一行有效位置置0,同样的道理可以到第四行,此时第四行的puzzle也决定了第五行的press的取值,这时候要满足第四行press和第五行的press共同作用后能够保证第五行的puzzle完全置0,此时的解就是有且仅有一个的。感觉说的还是不太清楚,之后补上一个更加详细的。

熄灯问题POJ1222的一些思考相关推荐

  1. POJ1222熄灯问题(枚举练习题)

    文章目录 题目描述 题目分析 代码(Java) 题目描述 这道题来自 POJ1222 ,题目描述如下: 有一个由按钮组成的矩阵,其中每行有 6 个按钮,共 5 行.每个按钮的位置上有一盏灯.当按下一个 ...

  2. C++基础算法学习——熄灯问题

    有一个由按钮组成的矩阵, 其中每行有6个按钮, 共5行 – 每个按钮的位置上有一盏灯 – 当按下一个按钮后, 该按钮以及周围位置(上边, 下边, 左边, 右边)的灯都会改变状态 26熄灯问题 POJ1 ...

  3. 关于寝室熄灯问题调研的思考

    **关于寝室熄灯问题调研的思考** 顶点二班 任彦州 入冬以来,宿舍实行了11:30熄灯的制度,但我常常听到身边同学抱怨熄灯后行动不便,等等.于是我们小组针决定对此问题深入调研. 初步调研中,我们先统 ...

  4. 算法基础:熄灯问题的思考

    算法基础:北京大学 问题描述 Bilibili搬运地址:https://www.bilibili.com/video/av10046345/?p=4 建议如果视频第一遍没看懂,再看一遍就好了~.~ 代 ...

  5. [真诚的思考](http://simplemind.info/blog/?p=423)

    周国平有一篇简短的自传.在文章里面,他提到了在北大的整个思想升华的过程.他说 我突然遇到了一个从未见过的全新型的人,他极其真诚,可以为思想而失眠,而发狂,而不要命.那些日子里,在宿舍熄灯之后,我常常在 ...

  6. 关于python导入模块和package的一些深度思考

    背景 在python中有导入模块和导入package一说,这篇文章主要介绍导入模块和package的一些思考. 首先什么是模块?什么是package? 模块:用来从逻辑上组织python代码(变量,函 ...

  7. 站在巨人的肩膀上“思考”问题,重在思考而不是拿来主义

    米老师按:觉得值得讨论的小文!我还要认真地想一想 主题:围绕职责链设计模式-计算收费有效时间博客展开讨论 参与人: 讨论时间: 讨论内容 这次讨论主要分为以下几点: 一.职责链模式应用于机房收费系统计 ...

  8. 由Node.js事件驱动模型引发的思考

    引言 近段时间听说了Node.js,很多文章表述这个事件驱动模型多么多么优秀,应用在服务器开发中有很大的优势,本身对此十分感性去,决定深入了解一下,由此也引发了一些对程序设计的思考,记录下来. 什么是 ...

  9. 看了极光推送技术原理的几点思考

    看了极光推送技术原理的几点思考 分类: android2012-11-26 20:50 16586人阅读 评论(18) 收藏 举报 目录(?)[+] 移动互联网应用现状 因为手机平台本身.电量.网络流 ...

最新文章

  1. 《松本行弘的程序世界》中文版原作者序
  2. 编程(创客)教育哪家强?图形化编程软件体验报告(慧编程)
  3. 谋定数字农业生态系统 万亿市场对话中国农民丰收节交易会
  4. 理解 Neutron FWaaS - 每天5分钟玩转 OpenStack(117)
  5. Vue3的响应式原理解析
  6. Qt文档阅读笔记-Qt4 Lower-Level API扩展Qt Applications(Qt4中Plugin的使用)解析与实例
  7. maven的仓库、生命周期与插件
  8. 设计sample语言的语法_Verilog语法之〇:Verilog HDL简介
  9. VC 2012 中调用WebBrowser简单的实现过程(图解过程)
  10. 朋友圈加粗字体数字_可爱搞笑的女生朋友圈文案
  11. 基于SRS的视频直播服务器搭建
  12. 消息中间件-Activemq之Master-Slaver
  13. linux驱动——内核通知链(探究i2c-dev.c 中的bus_register_notifier函数所得)
  14. Window10 和 Ubuntu20.04 双系统安装
  15. 服务器虚拟内存开机就90%,电脑开机物理内存就占了百分之90 为什么啊。
  16. 领域模型-软件需求分析
  17. Linux CentOS删除或重命名文件夹和文件的办法
  18. PWM调光调色温技术学习(笔记)
  19. 论文阅读笔记:YOLO9000: Better,Faster,Stronger
  20. PR调色 300婚礼视频调色视频颜色校正PR调色预设包

热门文章

  1. 怎么简化学生入校查询健康码和测温的流程-校园健康码查询平台,校园安防平台,家校互动平台
  2. Android学习笔记——活动,从创建到销毁
  3. 一文让你知道测试职业到底有哪些发展方向
  4. element-plus 源码学习——radio
  5. 关于《小萝莉的猴神大叔》些许体会
  6. MLX90614驱动,功能简介以及PEC校验
  7. 分享62个PHP源码,总有一款适合您
  8. Kotlin 之 lateinit关键字 与lazy
  9. 途志分享几个抖音短视频拍摄技巧
  10. java实现双色球生成器