poj 1222

http://poj.org/problem?id=1222

大意:熄灯游戏,给定一个5行6列的矩阵,表示30个灯,, 给定灯的初始状态,1表示开,0表示关,然后你可以操作,改变灯的状态,但是改灯的上下左右四个方向上的灯的状态也会改变,(开的变成关的,关的变成开的),,要求输出,你执行的操作。。1表示改变0表示未变。

解题思路:

方法一:枚举;

一共有30个灯,所以一共有2^30的改变方法。。一一枚举肯定会TLE,可以发现有这样的特点,当(i,j)上方的(i-1,j)为1时,(i,j)一定要变;当(i-1,j)为0时,(i,j)一定不能变。。可以这样考虑,只需枚举第一行的状态,就可以根据这种特点得出第二行,第三行,第四行,。。。的状态。。

 1 #include <iostream>
 2 
 3 using namespace std;
 4 int map[7][8],press[7][8];
 5 
 6 int text(){
 7     for(int i=2;i<=5;i++){//更新press
 8         for(int j=1;j<=6;j++){
 9             press[i][j] = (map[i-1][j]+press[i-1][j]+press[i-1][j-1]+press[i-1][j+1]+press[i-2][j])%2;
// (map[i-1][j]+press[i-1][j]+press[i-1][j-1]+press[i-1][j+1]+press[i-2][j])%2 表示的是map[i-1][j]的状态,press[i][j]肯定与其相同
10 } 11 } 12 for(int i=1;i<=6;i++){ 13 if((press[5][i-1]+press[5][i]+press[5][i+1]+map[5][i]+press[4][i])%2==1)//最后一行的状态。。若有开着的。。肯定不行 14 return 0; 15 } 16 return 1; 17 } 18 19 void get_press(){ 20 int i; 21 for(i=1;i<=6;i++) 22 press[1][i] =0; 23 while(!text()){ 24 press[1][1]++; 25 i=1; 26 while(press[1][i]==2){ 27 press[1][i]=0; 28 i++; 29 press[1][i]++; 30 } 31 } 32 } 33 34 int main() 35 { 36 int t; 37 cin>>t; 38 int cnt=1; 39 while(t--){ 40 for(int i=1;i<=5;i++) 41 for(int j=1;j<=6;j++) 42 cin>>map[i][j]; 43 get_press(); 44 cout<<"PUZZLE #"<<cnt++<<endl; 45 for(int i=1;i<=5;i++){ 46 for(int j=1;j<=5;j++){ 47 cout<<press[i][j]<<" "; 48 } 49 cout<<press[i][6]<<endl; 50 } 51 } 52 return 0; 53 }

方法二: 高斯消元。。还没看懂。。。

附链接:http://blog.csdn.net/shiren_Bod/article/details/5766907

原文地址:https://www.cnblogs.com/Bang-cansee/p/3242726.html