1222:熄灯问题
题目描述
有一个由按钮组成的矩阵,其中每行有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列的灯。
输入
输出
5行组成,每一行包括6个数字(0或1)。相邻两个数字之间用单个空格隔开。其中的1表示需要把对应的按钮按下,0则表示不需要按对应的按钮。样例输入
0 1 1 0 1 01 0 0 1 1 1
0 0 1 0 0 1
1 0 0 1 0 1
0 1 1 1 0 0
样例输出
1 0 1 0 0 11 1 0 1 0 1
0 0 1 0 1 1
1 0 0 1 0 0
0 1 0 0 0 0
5、这里就涉及到如何将这些01串转入char类型的数组中,我们应该设计一个函数。
char oriLights[6] = { 0 }; //oriLights[]应设置在main函数外面,方便使用
for (int i = 0; i < 5; i++)
{
for (int j = 5; j >= 0; j--)
{
int s;
cin >> s;
Set(&oriLights[i], j, s);
}
}
void Set(char *c, int i, int s)
{
*c |= (s << i);
}
如此便可以将每一行的01串写入每一个char类型的字符中。char result[6] = {0}; //结果,写下灯是否按下
char G[6] = {0}; //复制oriLights的数组
for(char temp = 0; temp < 64; temp++)
{
for(int i = 0; i < 6; i++)
{
G[i] = oriLights[i];
result[i] = 0;
}
result[0] = temp;
}
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char oriLights[6] = { 0 }; //oriLights[]应设置在main函数外面,方便使用
char result[6] = {0}; //结果,写下灯是否按下
char G[6] = {0}; //复制oriLights的数组
void Set(char *c, int i, int s) //录入每一个位的灯灭情况
{
*c |= (s << i);
}
void switchs(char *c) //对测试下灯灭情况进行修改
{
for(int i = 5; i >= 0; i--)
{
char temp = (1 << i);
char Temp = temp & *c;
if(Temp > 0)
{
G[0] ^=Temp;
G[1] ^=Temp;
if(i == 5)
{
G[0] ^= (Temp >> 1);
}
else if(i == 0)
{
G[0] ^= (Temp << 1);
}
else
{
G[0] ^= (Temp >> 1);
G[0] ^= (Temp << 1);
}
}
}
}
void change(int i, int j) //按提示4修改灯灭情况
{
char temp = G[i-1] & (1 << j);
result[i] |= temp;
if(temp > 0)
{
G[i-1] ^= temp;
G[i+1] ^= temp;
G[i] ^= temp;
if(j == 5)
{
G[i] ^= (temp >> 1);
}
else if(j == 0)
{
G[i] ^= (temp << 1);
}
else
{
G[i] ^= (temp >> 1);
G[i] ^= (temp << 1);
}
}
}
void input(char *c) //输出结果
{
for(int i = 5; i >= 0; i--)
{
char temp = *c & (1 << i);
if(temp > 0)
{
cout << "1 ";
}
else
{
cout << "0 ";
}
}
}
int main()
{
for(int i = 0; i < 5; i++)
{
oriLights[i] = 0;
}
for (int i = 0; i < 5; i++)
{
for (int j = 5; j >= 0; j--)
{
int s;
cin >> s;
Set(&oriLights[i], j, s);
}
}
for(char temp = 0; temp < 64; temp++)
{
for(int i = 0; i < 6; i++)
{
G[i] = oriLights[i];
result[i] = 0;
}
result[0] = temp;
switchs(&temp);
for(int i = 1; i < 5; i++)
{
for(int j = 5; j >= 0; j--)
{
change(i, j);
}
}
int nums = 0; //判断最后每个字符的ASCLL码的值是否为0,若是nums+1,当nums==5时表示在该情况下灯全灭
for(int i = 0; i < 5; i++)
{
if(G[i] == 0)
{
nums++;
}
}
if(nums==5)
{
for(int i = 0; i < 5; i++)
{
input(&result[i]);
cout << endl;
}
}
}
return 0;
}