算法基础(枚举)--- 熄灯问题(C语言)
描述:
有一个由按钮组成的矩阵,其中每行有6个按钮,共5行,每个按钮的位置有一盏灯,当按下一个按钮后,该按钮以及周围位置(上边,下边,左边,右边)的灯都会改变状态。
如果灯原来是点亮的就会被熄灭,原来是熄灭的则会被点亮。
在矩阵角上的按钮改变3盏灯的状态,在矩阵边上的按钮改变4盏灯的状态,其他的按钮改变5盏灯的状态。
给定矩阵中每盏灯的初始状态,求一种按按钮方案,使得所有的灯都熄灭。
输入:
第一行是一个正整数N,表示需要解决的案例数
每个案例由5行组成每一行包括6个数字这些数字以空格隔开,可以是0或1 0表示灯的初始状态是熄灭的1表示灯的初始状态是点亮的
输出:
对每个案例,首先输出一行,输出字符串“”PUZZLE #m",其中m是该案例的序号
接着按照该案例的输入格式输出5行
1表示需要把对应的按钮按下
0表示不需要按对应的按钮
每个数字以一个空格隔开
样例输入:
2
0 1 1 0 1 0
1 0 0 1 1 1
0 0 1 0 0 1
1 0 0 1 0 1
0 1 1 1 0 0
0 0 1 0 1 0
1 0 1 0 1 1
0 0 1 0 1 0
1 0 1 0 1 1
0 0 1 0 1 1
1 0 1 1 0 0
0 1 0 1 0 0
样例输出:
PUZZLE #1
1 0 1 0 0 1
1 1 0 1 0 1
0 0 1 0 1 1
1 0 0 1 0 0
0 1 0 0 0 0
PUZZLE #2
1 0 0 1 1 1
1 1 0 0 0 0
0 0 0 1 0 0
1 1 0 1 0 1
1 0 1 1 0 1
分析:
每个按钮最多按1次,多于1次没有意义。
想法1:枚举所有可能的开关状态,对每个状态计算一下最后灯的情况,看是否都熄灭。
共有30个开关,那么状态数就是2^30,会超时
想法2:(减少枚举的次数)
枚举第一行开关的状态,那么其余的都可以确定(因为第一行的各开关状态确定的情况下,将导致第一行有些灯是亮的,一些是灭的,要熄灭第一行某个亮着的灯,唯一的办法是按下第二行对应的开关,以此类推就都确定了)
因为数据不是0就是1,且每行只有6个数据,那么一行灯的状态用一个char类型的变量就可以存起来,因此只需要一个char类型的一维数组,且这个数组有5个元素。
如何枚举这64种状态
用二进制数来枚举,从0到63
每一个数对应第一行开关的一种状态
#include <stdio.h>
#include <string.h>
char oriLights[5]; //初始的灯的状态
char lights[5]; //变化中的灯
char result[5]; //最终的方案
int GetBit(char c, int i) //取字符c的第i个比特
{return (c >> i) & 1;
}
void SetBit(char* c, int i, int v)//设置字符的第i位为v
{if (v){*c |= (1 << i);}else*c &= ~(1 << i);
}
void FlipBit(char*c, int i)//翻转字符的第i位
{*c ^= (1 << i);
}
void OutputResult(int t, char result[])//输出结果
{printf("PUZZLE #%d\n",t);for (int i = 0; i < 5; i++){for (int j = 0; j < 6; j++){printf("%d", GetBit(result[i], j));if (j < 5)printf(" ");}printf("\n");}
}
int main()
{int T;scanf("%d", &T);//读入测试数据的组数for (int t = 1; t <= T; t++){for (int i = 0; i < 5; i++){for (int j = 0; j < 6; j++){int s;scanf("%d", &s);SetBit(&oriLights[i], j, s);}}for (int n = 0; n < 64; n++) //枚举第一行开关的所有状态{int switchs = n; //代表当前行的状态memcpy(lights, oriLights, sizeof(oriLights));for (int i = 0; i < 5; i++){result[i] = switchs;for (int j = 0; j < 6; j++){if (GetBit(switchs, j)) //对同一行灯的处理{if (j>0)FlipBit(&lights[i], j-1);FlipBit(&lights[i], j);if (j < 5)FlipBit(&lights[i], j + 1);}}if (i < 4) //对i+1行灯的处理{lights[i + 1] ^= switchs; //与1异或会翻转,与0异或不会}switchs = lights[i]; //第i+1行的状态}if (lights[4] == 0){OutputResult(t, result);break;}}}return 0;
}
算法基础(枚举)--- 熄灯问题(C语言)相关推荐
- OPJ 2.1基本算法之枚举:熄灯问题
OPJ 2.1基本算法之枚举 1813:熄灯问题 题目传送门 个人认为这是这一章为数不多不水的题之一--可能是我太弱了 思路: 既然这道题是枚举"算法"里的,那肯定就是要枚举.那么 ...
- 算法基础:熄灯问题的思考
算法基础:北京大学 问题描述 Bilibili搬运地址:https://www.bilibili.com/video/av10046345/?p=4 建议如果视频第一遍没看懂,再看一遍就好了~.~ 代 ...
- (一)算法基础——枚举
目录 枚举 例题 1.完美立方 2.生理周期 3.假币问题 枚举 基于逐个尝试答案的一种问题求解策略 例如: 求小于N的最大素数 – 找不到一个数学公式, 使得根据N就可以计算出这个素数 – N-1是 ...
- 枚举-熄灯问题(算法基础 第2周)
枚举-熄灯问题 问题讲解: 分析 讲解的很好了,再说就是画蛇添足. 源码 #include <stdio.h>int puzzle[6][8], press[6][8]; /* 推测验证过 ...
- 北大c语言算法基础<灌溉草场>
北大c语言算法基础 <灌溉草场>练习代码: #include<iostream> #include<queue> #define INFINITE 1 <&l ...
- 一篇解双链表(0基础看)(C语言)《数据结构与算法》
目录 序言 带头双向循环链表 1. 概念 2. 效果展示图 3. 接口实现 3.01. 本文章要实现的接口 3.02. 双链表的实现 3.03. 双链表的初始化 3.04. 打印链表 3.05. 动 ...
- 任务分配算法c语言程序,程序员算法基础——贪心算法
原标题:程序员算法基础--贪心算法 前言 贪心是人类自带的能力,贪心算法是在贪心决策上进行统筹规划的统称. 比如一道常见的算法笔试题跳一跳: 有n个盒子排成一行,每个盒子上面有一个数字a[i],表示最 ...
- 2022牛客寒假算法基础集训营3 签到题7题(附基础集训营1-3签到题总结)
1.A-智乃的Hello XXXX 签到 #include<bits/stdc++.h> using namespace std; int main(){cout<<" ...
- 《Python程序设计与算法基础教程(第二版)》江红 余青松,第九章课后习题答案
推荐阅读 <Python程序设计与算法基础教程(第二版)>江红 余青松 全部章节的课后习题,上机实践,课后答案,案例研究 文章目录 例9.1~例9.53 填空题:2 思考题:3~11 上机 ...
- 《Python程序设计与算法基础教程(第二版)》江红 余青松 全部章节的课后习题,上机实践,课后答案,案例研究
(还在更新中-) 这篇博客花费了我的大量时间和精力,从创作到维护:若认可本篇博客,希望给一个点赞.收藏 并且,遇到了什么问题,请在评论区留言,我会及时回复的 这本书对Python的知识点的描述很详细, ...
最新文章
- android 适配
- IOS UI 代码创建UIButton,UITextField,UILabel
- jdk动态代理源码学习
- spring的自生一个bug
- 一切为了孩子——一位IT麻麻的新西兰移民记录
- 微信十年,领取纪念勋章头像!
- 使用Gensim进行主题建模(二)
- mysql 有数据更新数据_MySQL之——实现无数据插入,有数据更新
- 数据仓库分层及模型设计
- 专业心理性格测试软件,what is my color心理性格测试
- 利用pyecharts绘制雷达图的案例(含参数解释)
- 普渡大学计算机图形,美国:普渡大学(UX方向)
- Androidstudio ADB调试
- odoo 使用打印功能
- 中科院1区JGG微生物专刊征稿
- Pandas数据分析——Task2
- Linux - 权限管理(用户)
- springboot打包docker镜像部署
- java.lang.NoSuchMethodError: No static method ..........
- 关于机器人状态估计(10)-VSLAM与VIO的3D建图,重定位与世界观综述