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;
}