熄灯问题
虽然这条题目也是一个枚举,但如果你每一种情况进行枚举可以预见的是必然会超时。
因此我们必须寻找更快的枚举方案
仔细观察可以发现,当你第一行的开关状态明确后,后面的行的开关也肯定是明确的。根据规则,你必须最迟在下一行的开关中熄灭上一行的灯,否则枚举方案失败。
- 只需枚举第一行的64种情况
- 使用位运算+一维字符数组来进行存储,方便。
//熄灯问题
#include <iostream>
#include <cmath>
#include <cstring>
#include<string>
using namespace std;
char oriLights[5];
char lights[5];
char result[5];
int getBit(char c,int i)
{
return (c>>i)&1;
}
void setBit(char & c,int i,int v)
{
if(v)
c|=(1<<i);
else c&=~(1<<i);
}
void flipBit(char & c,int i)
{
c^=(1<<i);
}
void print(char result[])
{
for(int j=0;j<5;++j)
{
for(int k=0;k<6;++k)
{
cout<<getBit(result[j],k)<<" ";
}
cout<<endl;
}
}
int main()
{
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)
{
char 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);
if(j<5) flipBit(lights[i],j+1);
flipBit(lights[i],j);
}
}
if(i<4) lights[i+1]^=switchs;//下一行和本行按钮进行亦或即可
switchs=lights[i];
}
if(lights[4]==0) break;
}
print(result);
return 0;
}
学会程序和算法,走遍天下都不怕
克什克腾旗阿斯哈图石林