POJ 1222 EXTENDED LIGHTS OUT
参考题解[https://mp.****.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;
}