这个看起来很像搜索类的题居然是一道普通枚举,这让我想起来了寒假计蒜客同样是开关灯的问题
这类问题感觉有一定类似,以这道题为例,一盏灯摁两次就会回到原来的状态,所以只用摁一次,采用的思想是枚举第一行按钮的全部状态,根据这个状态首先开关灯,之后从第二行开始判断,如果上一行正上方的灯还是亮着的这个按钮就要按下,直到按完最后一行的按钮,这样所有灯的亮暗已经被确定了,遍历灯,如果全是0状态 就输出
网上看的代码都太复杂了。。。像我这种辣鸡还是用点简单的代码
(我永远也不会用if-else的 …………真香!)
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <cstring>
#include <cmath>
#include <cstdlib>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
/*
POJ 1222熄灯问题
题目分析:由于一个灯摁两次就会产生抵消效果 所以每一个灯
要不不摁,要不就摁一次
摁灯先后顺序无关
直接枚举所有可能开关状态
2^30
->枚举局部
第一行开关确定以后,就可以知道后边几行的状态了
下边一行的开关控制上边一行
*/
int main(int argc, char** argv) {
int n;
scanf("%d",&n);
int count = 0;
while(n--)
{
count ++;
int bulb[50][50];//储存灯的状态
for(int i=0;i<5;i++)
{
for(int j=0;j<6;j++)
{
scanf("%d",&bulb[i][j]);
}
}
//枚举模拟 首先枚举第一行
for(int a=0;a<2;a++)
{
for(int b=0;b<2;b++)
{
for(int c=0;c<2;c++)
{
for(int d=0;d<2;d++)
{
for(int e=0;e<2;e++)
{
for(int f=0;f<2;f++)
{
//这里开始做题
int kaiguan[50][50];
memset(kaiguan,0,sizeof(kaiguan));
int temp[50][50];//每次用一个新的
for(int i=0;i<5;i++)
{
for(int j=0;j<6;j++)
{
temp[i][j] = bulb[i][j];
}
}
for(int i=0;i<6;i++)
{
kaiguan[0][0] = a;
kaiguan[0][1] = b;
kaiguan[0][2] = c;
kaiguan[0][3] = d;
kaiguan[0][4] = e;
kaiguan[0][5] = f;
}
//灯泡的亮暗存储在了temp中
for(int i=0;i<6;i++)
{
if(kaiguan[0][i]==1)//如果按下了开关
{
//自己
if(temp[0][i]==1)
{
temp[0][i] = 0;
goto a1;
}
if(temp[0][i]==0)
{
temp[0][i] = 1;
goto a1;
}
a1:
//下边
if(temp[0+1][i]==1)
{
temp[0+1][i] = 0;
goto a2;
}
if(temp[0+1][i]==0)
{
temp[0+1][i] = 1;
goto a2;
}
a2:
//左边
if(i-1>=0)
{
if(temp[0][i-1]==1)
{
temp[0][i-1] = 0;
goto a3;
}
if(temp[0][i-1]==0)
{
temp[0][i-1] = 1;
goto a3;
}
}
a3:
//右边
if(i+1<=5)
{
if(temp[0][i+1]==1)
{
temp[0][i+1] = 0;
goto a4;
}
if(temp[0][i+1]==0)
{
temp[0][i+1] = 1;
goto a4;
}
}
a4:;
}
}//第一行处理完毕
for(int i=1;i<5;i++)//开始从第二行开始按
{
for(int j=0;j<6;j++)
{
if(temp[i-1][j]==1)//如果上一行存在亮的
{
kaiguan[i][j] = 1;//这个位置要按
//改变其四周和自己状态
//自己
if(temp[i][j]==0)
{
temp[i][j] = 1;
// goto b1;
}
else if(temp[i][j]==1)
{
temp[i][j] = 0;
// goto b1;
}
//b1:
//上边
if(temp[i-1][j]==0)
{
temp[i-1][j] = 1;
goto b2;
}
if(temp[i-1][j]==1)
{
temp[i-1][j] = 0;
goto b2;
}
b2:
//下边
if(i+1<=4)
{
if(temp[i+1][j]==0)
{
temp[i+1][j] = 1;
goto b3;
}
if(temp[i+1][j]==1)
{
temp[i+1][j] = 0;
goto b3;
}
}
b3:
//左边
if(j-1>=0)
{
if(temp[i][j-1]==0)
{
temp[i][j-1] = 1;
goto b4;
}
if(temp[i][j-1]==1)
{
temp[i][j-1] = 0;
goto b4;
}
}
b4:
//右边
if(j+1<=5)
{
if(temp[i][j+1]==0)
{
temp[i][j+1] = 1;
goto b5;
}
if(temp[i][j+1]==1)
{
temp[i][j+1] = 0;
goto b5;
}
}
b5:;
// printf("\n------------------------------------------\n");
// for(int i=0;i<5;i++)
// {
// for(int j=0;j<6;j++)
// {
// printf("%d ",temp[i][j]);
// }
// printf("\n");
// }
// printf("\n------------------------------------------\n");
// system("pause");
}
}
}
int flag = 0;
for(int i=0;i<5;i++)
{
for(int j=0;j<6;j++)
{
if(temp[i][j]==1)
{
flag = 1;
goto M;
}
}
}
M:
if(flag==0)
{
printf("PUZZLE #%d\n",count);
for(int i=0;i<5;i++)
{
for(int j=0;j<6;j++)
{
printf("%d ",kaiguan[i][j]);
}
printf("\n");
}
}
}
}
}
}
}
}
}
//system("pause");
return 0;
}
/*
for(int i=0;i<5;i++)
{
for(int j=0;j<6;j++)
{
printf("%d ",temp[i][j]);
}
printf("\n");
}
system("pause");
*/