[poj1813]熄灯问题
Description
有一个由按钮组成的矩阵,其中每行有6个按钮,共5行。每个按钮的位置上有一盏灯。当按下一个按钮后,该按钮以及周围位置(上边、下边、左边、右边)的灯都会改变一次。即,如果灯原来是点亮的,就会被熄灭;如果灯原来是熄灭的,则会被点亮。在矩阵角上的按钮改变3盏灯的状态;在矩阵边上的按钮改变4盏灯的状态;其他的按钮改变5盏灯的状态。
在上图中,左边矩阵中用X标记的按钮表示被按下,右边的矩阵表示灯状态的改变。对矩阵中的每盏灯设置一个初始状态。请你按按钮,直至每一盏等都熄灭。与一盏灯毗邻的多个按钮被按下时,一个操作会抵消另一次操作的结果。在下图中,第2行第3、5列的按钮都被按下,因此第2行、第4列的灯的状态就不改变。
请你写一个程序,确定需要按下哪些按钮,恰好使得所有的灯都熄灭。根据上面的规则,我们知道1)第2次按下同一个按钮时,将抵消第1次按下时所产生的结果。因此,每个按钮最多只需要按下一次;2)各个按钮被按下的顺序对最终的结果没有影响;3)对第1行中每盏点亮的灯,按下第2行对应的按钮,就可以熄灭第1行的全部灯。如此重复下去,可以熄灭第1、2、3、4行的全部灯。同样,按下第1、2、3、4、5列的按钮,可以熄灭前5列的灯。
Input
5行组成,每一行包括6个数字(0或1)。相邻两个数字之间用单个空格隔开。0表示灯的初始状态是熄灭的,1表示灯的初始状态是点亮的。
Output
5行组成,每一行包括6个数字(0或1)。相邻两个数字之间用单个空格隔开。其中的1表示需要把对应的按钮按下,0则表示不需要按对应的按钮。
Sample Input
0 1 1 0 1 0
1 0 0 1 1 1
0 0 1 0 0 1
1 0 0 1 0 1
0 1 1 1 0 0
Sample Output
1 0 1 0 0 1
1 1 0 1 0 1
0 0 1 0 1 1
1 0 0 1 0 0
0 1 0 0 0 0
Solution
一道模拟题,注意不是模拟整个矩阵的点击情况,而只是模拟第一行的点击情况,获得第一行点击后的状态,以此确定第二行的点击方案,再模拟第二行的点击后状态,确定第三行的方案······以此类推。当点完第五行后,检查第五行是否有亮灯,若有,则表示此方案不正确,否则选择此方案。
…如何获取下一行方案?
若第i行第j列亮灯,则第i+1行第j列要点击,否则不点。
Code
/*
Name: light.cpp
Author: YuckXi
Date: 14-01-19 18:57
*/
#include<iostream>
#include<string>
#include<bits/stdc++.h>
using namespace std;
int doit[65][7]={//打表,模拟第一行的点击情况
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,1,0,0,0,0,0},
{0,0,1,0,0,0,0},
{0,1,1,0,0,0,0},
{0,0,0,1,0,0,0},
{0,1,0,1,0,0,0},
{0,0,1,1,0,0,0},
{0,1,1,1,0,0,0},
{0,0,0,0,1,0,0},
{0,1,0,0,1,0,0},
{0,0,1,0,1,0,0},
{0,1,1,0,1,0,0},
{0,0,0,1,1,0,0},
{0,1,0,1,1,0,0},
{0,0,1,1,1,0,0},
{0,1,1,1,1,0,0},
{0,0,0,0,0,1,0},
{0,1,0,0,0,1,0},
{0,0,1,0,0,1,0},
{0,1,1,0,0,1,0},
{0,0,0,1,0,1,0},
{0,1,0,1,0,1,0},
{0,0,1,1,0,1,0},
{0,1,1,1,0,1,0},
{0,0,0,0,1,1,0},
{0,1,0,0,1,1,0},
{0,0,1,0,1,1,0},
{0,1,1,0,1,1,0},
{0,0,0,1,1,1,0},
{0,1,0,1,1,1,0},
{0,0,1,1,1,1,0},
{0,1,1,1,1,1,0},
{0,0,0,0,0,0,1},
{0,1,0,0,0,0,1},
{0,0,1,0,0,0,1},
{0,1,1,0,0,0,1},
{0,0,0,1,0,0,1},
{0,1,0,1,0,0,1},
{0,0,1,1,0,0,1},
{0,1,1,1,0,0,1},
{0,0,0,0,1,0,1},
{0,1,0,0,1,0,1},
{0,0,1,0,1,0,1},
{0,1,1,0,1,0,1},
{0,0,0,1,1,0,1},
{0,1,0,1,1,0,1},
{0,0,1,1,1,0,1},
{0,1,1,1,1,0,1},
{0,0,0,0,0,1,1},
{0,1,0,0,0,1,1},
{0,0,1,0,0,1,1},
{0,1,1,0,0,1,1},
{0,0,0,1,0,1,1},
{0,1,0,1,0,1,1},
{0,0,1,1,0,1,1},
{0,1,1,1,0,1,1},
{0,0,0,0,1,1,1},
{0,1,0,0,1,1,1},
{0,0,1,0,1,1,1},
{0,1,1,0,1,1,1},
{0,0,0,1,1,1,1},
{0,1,0,1,1,1,1},
{0,0,1,1,1,1,1},
{0,1,1,1,1,1,1}
};
struct mat{//记录矩阵的结构体
int a[6][7];
void get(){//读入
bool g;
for(int i=1;i<=5;i++){
for(int j=1;j<=6;j++){
cin>>g;
a[i][j]=g;
}
}
}
void out(){//输出
for(int i=1;i<=5;i++){
for(int j=1;j<=6;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
void clear(){//清零
for(int i=1;i<=5;i++){
for(int j=1;j<=6;j++){
a[i][j]=0;
}
}
}
void push(int x,int y){//模拟点击事件
a[x][y]^=1;
a[x][y+1]^=1;
a[x][y-1]^=1;
a[x-1][y]^=1;
a[x+1][y]^=1;
}
}a,b,c;
int main(){
a.get();
b=a;
for(int i=1;i<=64;i++){
for(int j=1;j<=6;j++){//第1行点击
if(doit[i][j]){
c.a[1][j]=1;
b.push(1,j);
}
}
for(int j=1;j<=6;j++){//确认第二行方案
if(b.a[1][j]){
c.a[2][j]=1;
}
}
for(int j=1;j<=6;j++){
if(c.a[2][j]){
b.push(2,j);
}
}
for(int j=1;j<=6;j++){
if(b.a[2][j]){
c.a[3][j]=1;
}
}
for(int j=1;j<=6;j++){
if(c.a[3][j]){
b.push(3,j);
}
}
for(int j=1;j<=6;j++){
if(b.a[3][j]){
c.a[4][j]=1;
}
}
for(int j=1;j<=6;j++){
if(c.a[4][j]){
b.push(4,j);
}
}
for(int j=1;j<=6;j++){
if(b.a[4][j]){
c.a[5][j]=1;
}
}
for(int j=1;j<=6;j++){
if(c.a[5][j]){
b.push(5,j);
}
}
for(int j=1;j<=6;j++){//检查是否完全熄灭
if(b.a[5][j]){
goto saygoodbye;
}
}
c.out();
return 0;//输出+退出
saygoodbye:;
c.clear();
b=a;//再来
}
}
无注释版
#include<iostream>
#include<string>
#include<bits/stdc++.h>
using namespace std;
int doit[65][7]={
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,1,0,0,0,0,0},
{0,0,1,0,0,0,0},
{0,1,1,0,0,0,0},
{0,0,0,1,0,0,0},
{0,1,0,1,0,0,0},
{0,0,1,1,0,0,0},
{0,1,1,1,0,0,0},
{0,0,0,0,1,0,0},
{0,1,0,0,1,0,0},
{0,0,1,0,1,0,0},
{0,1,1,0,1,0,0},
{0,0,0,1,1,0,0},
{0,1,0,1,1,0,0},
{0,0,1,1,1,0,0},
{0,1,1,1,1,0,0},
{0,0,0,0,0,1,0},
{0,1,0,0,0,1,0},
{0,0,1,0,0,1,0},
{0,1,1,0,0,1,0},
{0,0,0,1,0,1,0},
{0,1,0,1,0,1,0},
{0,0,1,1,0,1,0},
{0,1,1,1,0,1,0},
{0,0,0,0,1,1,0},
{0,1,0,0,1,1,0},
{0,0,1,0,1,1,0},
{0,1,1,0,1,1,0},
{0,0,0,1,1,1,0},
{0,1,0,1,1,1,0},
{0,0,1,1,1,1,0},
{0,1,1,1,1,1,0},
{0,0,0,0,0,0,1},
{0,1,0,0,0,0,1},
{0,0,1,0,0,0,1},
{0,1,1,0,0,0,1},
{0,0,0,1,0,0,1},
{0,1,0,1,0,0,1},
{0,0,1,1,0,0,1},
{0,1,1,1,0,0,1},
{0,0,0,0,1,0,1},
{0,1,0,0,1,0,1},
{0,0,1,0,1,0,1},
{0,1,1,0,1,0,1},
{0,0,0,1,1,0,1},
{0,1,0,1,1,0,1},
{0,0,1,1,1,0,1},
{0,1,1,1,1,0,1},
{0,0,0,0,0,1,1},
{0,1,0,0,0,1,1},
{0,0,1,0,0,1,1},
{0,1,1,0,0,1,1},
{0,0,0,1,0,1,1},
{0,1,0,1,0,1,1},
{0,0,1,1,0,1,1},
{0,1,1,1,0,1,1},
{0,0,0,0,1,1,1},
{0,1,0,0,1,1,1},
{0,0,1,0,1,1,1},
{0,1,1,0,1,1,1},
{0,0,0,1,1,1,1},
{0,1,0,1,1,1,1},
{0,0,1,1,1,1,1},
{0,1,1,1,1,1,1}
};
struct mat{
int a[6][7];
void get(){
bool g;
for(int i=1;i<=5;i++){
for(int j=1;j<=6;j++){
cin>>g;
a[i][j]=g;
}
}
}
void out(){
for(int i=1;i<=5;i++){
for(int j=1;j<=6;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
void clear(){
for(int i=1;i<=5;i++){
for(int j=1;j<=6;j++){
a[i][j]=0;
}
}
}
void push(int x,int y){
a[x][y]^=1;
a[x][y+1]^=1;
a[x][y-1]^=1;
a[x-1][y]^=1;
a[x+1][y]^=1;
}
}a,b,c;
int main(){
a.get();
b=a;
for(int i=1;i<=64;i++){
for(int j=1;j<=6;j++){
if(doit[i][j]){
c.a[1][j]=1;
b.push(1,j);
}
}
for(int j=1;j<=6;j++){
if(b.a[1][j]){
c.a[2][j]=1;
}
}
for(int j=1;j<=6;j++){
if(c.a[2][j]){
b.push(2,j);
}
}
for(int j=1;j<=6;j++){
if(b.a[2][j]){
c.a[3][j]=1;
}
}
for(int j=1;j<=6;j++){
if(c.a[3][j]){
b.push(3,j);
}
}
for(int j=1;j<=6;j++){
if(b.a[3][j]){
c.a[4][j]=1;
}
}
for(int j=1;j<=6;j++){
if(c.a[4][j]){
b.push(4,j);
}
}
for(int j=1;j<=6;j++){
if(b.a[4][j]){
c.a[5][j]=1;
}
}
for(int j=1;j<=6;j++){
if(c.a[5][j]){
b.push(5,j);
}
}
for(int j=1;j<=6;j++){
if(b.a[5][j]){
goto saygoodbye;
}
}
c.out();
return 0;
saygoodbye:;
c.clear();
b=a;
}
}