POJ-1222 EXTENDED LIGHTS OUT【暴力枚舉】
題目鏈接:http://poj.org/problem?id=1222
題意:(開關問題)5*6的矩陣,按下一個燈其上下左右的燈隨之變化,求如何操作使得燈都熄滅
**題解:**5*6的數據很小,可以暴力枚舉情況。首先枚舉第一行的所有情況2^6 = 64 種情況(000000、100000、010000、110000……)再根據上一個行的狀態處理,最後根據最後一行的狀態判斷
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
#include <cmath>
using namespace std;
#define eps 1e-6
#define pi 3.14159265359
typedef long long LL;
typedef long double LD;
const int maxn = 10;
int n,m,t;
int a[maxn][maxn],b[maxn][maxn];
int flag[maxn][maxn];
int dir[4][2]={0,1,0,-1, 1,0,-1,0}; // 方向向量,(x,y)周圍的四個方向
int Check(int x,int y){//判斷條件
if( x>=1 && x<=n && y>=1 && y<=m ) return 1;
else return 0;
}
void pre(int x,int y){//按鍵操作
a[x][y] = !a[x][y]; //邏輯非
for(int i=0;i<4;i++){
int xx = x+dir[i][0],yy = y+dir[i][1];
if(Check(xx,yy) ){
a[xx][yy] = !a[xx][yy];
}
}
}
void fun(){
int _flag = 0;
int k = 1;
while(k<=64){//第一行開關情況:2^6種
memcpy(a,b,sizeof(b));
memset(flag,0,sizeof(flag));
for(int i=0;i<=5;i++){//列舉第一行所有開關情況
if(k&(1<<i) ){
pre(1,1+i);
flag[1][1+i] = 1;
}
}
for(int i=2;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i-1][j]){
pre(i,j);
flag[i][j] = 1;
}
}
}
int flag_ = 1;
for(int i=1;i<=m;i++){
if(a[5][i]){//不爲0不滿足
flag_ = 0;
break;
}
}
if(flag_){
for(int i=1; i<=n; i++){
for(int j=1; j<m; j++)
printf("%d ",flag[i][j]);
printf("%d\n",flag[i][6]);
}
break;
}
k++;
}
}
int main(){
scanf("%d",&t);
n=5,m=6;
for(int k=1;k<=t;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&b[i][j]);
}
}
printf("PUZZLE #%d\n",k);
fun();
}
return 0;
}