POJ 1222.EXTENDED LIGHTS OUT

这个看起来很像搜索类的题居然是一道普通枚举,这让我想起来了寒假计蒜客同样是开关灯的问题

这类问题感觉有一定类似,以这道题为例,一盏灯摁两次就会回到原来的状态,所以只用摁一次,采用的思想是枚举第一行按钮的全部状态,根据这个状态首先开关灯,之后从第二行开始判断,如果上一行正上方的灯还是亮着的这个按钮就要按下,直到按完最后一行的按钮,这样所有灯的亮暗已经被确定了,遍历灯,如果全是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"); 
									
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值