熄灯问题 学习笔记
发布日期:2021-07-22 07:29:00 浏览次数:4 分类:技术文章

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

思路

就是当第一行开关按下后灯状态确定,向下逐行可以有一个确定的开关状态使得上一行的灯一定全部熄灭,直到最后一行检查是否也全部熄灭,如果是则得到结果。这里只需要枚举第一行所有开关的状态即可,更巧妙的是可以采用二进制位运算节省空间。

代码

#include 
#include
#include
using namespace std;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) {
//修改c的第i位 if (v) {
c |= (1 << i); } else {
c &= ~(1 << i); }}void FlipBit(char& c, int i) {
//反转c的第i位 c ^= (1 << i);}void OutputResult(int t, char result[]) {
//输出结果 cout << "###" << t << endl; for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 6; ++j) {
cout << GetBit(result[i], j); if (j < 5) cout << " "; } cout << endl; }}int main(){
int T; cin >> T; for (int t = 1; t <= T; ++t) {
for (int i = 0; i < 5; ++i) for (int j = 0; j < 6; ++j) {
int s; cin >> s; SetBit(oriLights[i], j, s); } for (int n = 0; n < 64; ++n) {
int switchs = n; //第一行按开关策略(开始枚举,共2^6种可能) 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; switchs = lights[i]; //要让本行全熄灭,下一行开关状态已经确定 } if (lights[4] == 0) {
OutputResult(t, result); break; } } }}

转载地址:https://blog.csdn.net/m0_45689014/article/details/113854543 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:牛客网 KY2 成绩排序
下一篇:PTA基础编程题目集 7-38 数列求和-加强版

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月23日 15时35分33秒