問題描述
有一個由按鈕組成的矩陣, 其中每行有 6 個按鈕, 共5 行。每個按鈕的位置上有一盞燈。當按下一個按鈕后,該按鈕以及周圍位置(上邊、下邊、左邊、右邊)的燈都會改變一次。即,如果燈原來是點亮的,就會被熄滅;如果燈原來是熄滅的,則會被點亮。在矩陣角上的按鈕改變 3 盞燈的狀態;在矩陣邊上的按鈕改變 4 盞燈的狀態;其他的按鈕改變 5 盞燈的狀態。在下圖 1 中,左邊矩陣中用 X 標記的按鈕表示被按下,右邊的矩陣表示燈狀態的改變。與一盞燈毗鄰的多個按鈕被按下時,一次操作會抵消另一次操作的結果。在圖 2 中,第 2行第 3、5 列的按鈕都被按下,因此第 2 行、第 4 列的燈的狀態就不改變。根據上面的規則,我們知道:
- 第 2 次按下同一個按鈕時,將抵消第 1 次按下時所產生的結果。因此,每個按鈕最多只需要按下一次。
- 各個按鈕被按下的順序對最終的結果沒有影響。
- 對第 1 行中每盞點亮的燈,按下第 2 行對應的按鈕,就可以熄滅第 1 行的全部燈。如此重復下去,可以熄滅第 1、2、3、4 行的全部燈。同樣,按下第 1、2、3、4、5 列的按鈕,可以熄滅前 5 列的燈。
對矩陣中的每盞燈設置一個初始狀態。請你寫一個程序,確定需要按下哪些按鈕,恰好使得所有的燈都熄滅。
熄燈問題
輸入
第一行是一個正整數 N,表示需要解決的案例數。每個案例由 5 行組成,每一行包括 6個數字。這些數字以空格隔開,可以是 0 或 1。0 表示燈的初始狀態是熄滅的,1 表示燈的初始狀態是點亮的。
輸出
對每個案例,首先輸出一行,輸出字符串“PUZZLE #m”,其中 m 是該案例的序號。接著按照該案例的輸入格式輸出 5 行,其中的 1 表示需要把對應的按鈕按下,0 則表示不需要按對應的按鈕。每個數字以一個空格隔開。
輸入樣列
2
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
0 0 1 0 1 0
1 0 1 0 1 1
0 0 1 0 1 1
1 0 1 1 0 0
0 1 0 1 0 0
輸出樣例
PUZZLE #1
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
PUZZLE #2
1 0 0 1 1 1
1 1 0 0 0 0
0 0 0 1 0 0
1 1 0 1 0 1
1 0 1 1 0 1
算法實現
using System;
namespace Questions{
class Program{
public static void Main(string[] args){
int n = int.Parse(Console.ReadLine());
for (int k = 1; k <= n; k++)
{
int[,] num = new int[6, 8];
for (int i = 1; i < 6; i++)
{
string input = Console.ReadLine();
string[] data = input.Split();
for (int j = 1; j < 7; j++)
num[i, j] = int.Parse(data[j - 1]);
}
int[,] result = new int[6, 8];
int l = 0;
while (!IsSuccess(num, ref result))
{
result[1, 1]++;
l = 1;
while (result[1, l] > 1)
{
result[1, l] = 0;
result[1, ++l]++;
}
}
Console.WriteLine("PUZZLE #{0}", k);
for (int i = 1; i < 6; i++)
{
for (int j = 1; j < 7; j++)
{
Console.Write("{0} ", result[i, j]);
}
Console.WriteLine();
}
Console.WriteLine();
}
Console.ReadKey();
}
public static bool IsSuccess(int[,] num, ref int[,] result)
{
for (int i = 1; i < 5; i++)
for (int j = 1; j < 7; j++)
result[i + 1, j] = (num[i, j] + result[i, j] + result[i - 1, j] + result[i, j - 1] + result[i, j + 1]) % 2;
for (int j = 1; j < 7; j++)
if ((result[5, j] + result[5, j - 1] + result[5, j + 1] + result[4, j]) % 2 != num[5, j])
return false;
return true;
}
}
}