您的位置:首页 > 其它

POJ-1222 EXTENDED LIGHTS OUT【暴力枚举】

2016-08-15 20:03 375 查看

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  POJ 暴力