參考題解[https://mp.csdn.net/mdeditor/87896325#]
#include <iostream>
#include <cstring>
using namespace std;
//取c的第i位
int GetBit(char c, int i)
{
return (c >> i) & 1; //先右移再與1相與
}
//設置c的第i位爲v
void SetBit(char &c, int i, int v)
{
if(v)
c |= (1 << i); //將第i位設置爲1
else
c &= ~(1 << i); // 第i位設置爲0,其餘爲1,再進行與運算
}
//將c的第i位取反
void Flip(char &c, int i)
{
c ^= (1 << i); //第i位與1異或進行取反
}
void OutputResult(int t, char result[]) //輸出結果
{
cout << "PUZZLE #" << t << endl;
for(int i=0; i<5; i++) //5行
{
for(int j=0; j<6; j++)
{
cout << GetBit(result[i], j); //得到第i行第j列元素
if(j < 5)
cout << " "; // 輸出5個空格最後一個不輸出空格
}
cout << endl;
}
}
int main()
{
char oriLights[5]; //最初燈矩陣,一個比特表示一盞燈,一個數組元素表示一行6個
char lights[5]; //不停變化的燈矩陣
char result[5]; //結果開關矩陣
char switchs; //某一行的開關狀態
int T;
cin >> T;
for(int t=1; t<=T; t++)
{
memset(oriLights, 0, sizeof(oriLights)); //清零
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++) //遍歷首行開關的64種狀態
{
memcpy(lights, oriLights, sizeof(oriLights)); //複製,每一次循環在原始數組上操作
switchs = n; //第i行的開關狀態
for(int i=0; i<5; i++)
{
result[i] = switchs; //第i行的開關方案
for(int j=0; j<6; j++)
{
if(GetBit(switchs, j))
{
if(j > 0)
Flip(lights[i], j-1); //改左燈
Flip(lights[i], j); //改開關位置的燈
if(j < 5)
Flip(lights[i], j+1); //改右燈
}
}
if(i < 4)
lights[i+1] ^= switchs; //改下一行的燈
switchs = lights[i]; //第i+1行開關方案和第i行燈的情況相同
}
if(lights[4] == 0)
{
OutputResult(t, result);
break;
}
}
}
return 0;
}