终于有时间自己写一遍了,然后本菜鸡昨天一整夜都在debug……多亏XHL发现了我的数组越界……太艰难了
思路:穷举第一行,因为完成了一行的操作以后,要关掉第一行的灯,只能从第二行下手,也就是说,第二行的操作和第一行的状态相同,依此类推。最后检查最后一行,如果关好了,就退出穷举循环,输出结果。
菜鸡代码:
#include <iostream>
#include <cstring>
using namespace std;
int a[5][6],b[5][6],ans[5][6];
void SwapLight(int i,int j) {
a[i][j]=!a[i][j];//自己
if(i) a[i-1][j]=!a[i-1][j];//上
if(j) a[i][j-1]=!a[i][j-1];//左
if(i!=4) a[i+1][j]=!a[i+1][j];//下
if(j!=5) a[i][j+1]=!a[i][j+1];//右
}
void SwapLine(int line) {
for(int i=0; i<6; i++)
if(ans[line][i])SwapLight(line,i);
}
bool Check() {//只需要检查最后一行
for(int j=0; j<6; j++)
if(a[4][j])return 0;
return 1;
}
void Geta(int k) {//获取第一行的操作
for(int i=0; i<6; i++) {
ans[0][i]=(k>>i)&1;
}
}
void Solve() {//优化穷举
for(int k=0; k<64; k++) {
memcpy(a,b,sizeof(b));
memset(ans,0,sizeof(ans));
Geta(k);
for(int i=1; i<5; i++) {
SwapLine(i-1);
for(int j=0; j<6; j++) {
if(a[i-1][j]) ans[i][j]=1;
}
}
SwapLine(4);
if(Check()) return;
}
cout<<"ERROR"<<endl;
}
int main() {
int t;
cin>>t;
for(int PU=1; PU<=t; PU++) {
for(int i=0; i<5; i++)
for(int j=0; j<6; j++)
cin>>b[i][j];
Solve();
cout<<"PUZZLE #"<<PU<<endl;
for(int i=0; i<5; i++) {
for(int j=0; j<6; j++) {
cout<<ans[i][j];
if(j!=5)cout<<" ";
}
cout<<endl;
}
}
return 0;
}郭炜老师的代码:
#include <cstring>
#include <iostream>
using namespace std;
int GetBit(int c,int i) {//取c的第i位
return ( c >> i ) & 1;
}
void SetBit(int & c,int i, int v) {//设置c的第i位为v
if( v ) c |= ( 1 << i);//如果v==1 或
else c &= ~( 1 << i);//置零
}
void Flip(int & c, int i) {//将c的第i位为取反
c ^= ( 1 << i);
//1^0=1 0^0=0 A^0=A
//A^1=!A
//c ^= ( 1 << i); 这种写法可以对一个数操作 可以理解为一个二进制字串
}
void OutputResult(int t,int result[]) { //输出结果
cout << "PUZZLE #" << 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 oriLights[5];//最初灯矩阵,一个比特表示一盏灯
int lights[5]; //不停变化的灯矩阵
int result[5]; //结果开关矩阵
int 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;
}再次吐槽牛客网不适合写博客 我明明排好版了,因为tab所占字符数设置不一样又乱了,还不如笔记软件……

京公网安备 11010502036488号