總時間限制: 1000ms
記憶體限制: 65536kb
描述
有乙個由按鈕組成的矩陣,其中每行有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)。相鄰兩個數字之間用單個空格隔開。0表示燈的初始狀態是熄滅的,1表示燈的初始狀態是點亮的。
輸出
5行組成,每一行包括6個數字(0或1)。相鄰兩個數字之間用單個空格隔開。其中的1表示需要把對應的按鈕按下,0則表示不需要按對應的按鈕。
樣例輸入
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
樣例輸出
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
題意:給出乙個燈矩陣[5x6],要求將矩陣裡面的燈全部熄滅。問如何按?
思路:題目給出了許多提示。甚至把解法都告訴我們了:
關於順序的問題,有點難以明白,不過我們可以知道:
因此順序無關緊要。
然後,題目還把解法告訴了我們……
對於這個題,很容易想到可以用2進製數,列舉所有的狀態,來對應相應的按按鈕的方案,[0,
2n)[0, 2^n)
[0,2n)
,有2
302^
230個方案,再加上按按鈕和判斷的時間消耗……複雜度絕對爆表!
而題目則告訴我們,可以從第一行開始,對第1行中每盞點亮的燈,按下第2行對應的按鈕,就可以熄滅第1行的全部燈,如此重複下去,可以熄滅第1、2、3、4行的全部燈。只要在對第4行的每盞點亮的燈,按下第5行對應的按鈕,熄滅第4行的全部燈後,檢查第5行的燈是否全部熄滅了即可判斷方案是否可行。複雜度降到了26=
642^6 = 64
26=6
4個狀態,因為只需要列舉第一行的狀態。
這是很重要的列舉優化的技巧。
如果存在某個區域性,一旦這個區域性的狀態被確定,那麼其他剩餘部分的狀態只能是確定的一種或不多的n種,那麼只需列舉這個區域性的狀態即可。本題的這個區域性就是第一行:
只要第1行的狀態定下來,記作a,那麼剩餘行的情況就是確定唯一的了。
推算出最後一行的開關狀態,然後看看最後一行的開關起作用後,最後一行的所有燈是否都熄滅: 如果是, 那麼a就是乙個解的狀態;如果不是,那麼a不是解的狀態,第1行換個狀態重新試試。
照這樣說,……,第一列不也是乙個區域性狀態嗎?對,而且只用列舉第一列,狀態個數為25=
322^5=32
25=32!
所以,我的答案就列舉第一列。
看到別人的答案,發現了新技巧。
由於矩陣資料要麼是0,要麼是1,每一行只有6個字元,因此可以用乙個char[5]
儲存整個矩陣。每乙個char
儲存一行的資料。這不僅節約了一點空間,而且有時候很容易對整行進行操作,如設定整行和比較,提高了效率。唯一麻煩的就是要進行位操作。
#include
#include
using
namespace std;
intgetbit
(char c,
int i)
void
setbit
(char
&c,int i,
int v)
void
flip
(char
&c,int i)
void
outputresult
(char result)
cout << endl;}}
intmain()
}for
(int n =
0; n <64;
++n)}if
(i <4)
//不是最後一行
lights[i +1]
^= switchs;
//改下一行的燈
switchs = lights[i]
;//第i+1行開關方案和第i行燈相同 }if
(lights[4]
==0)}
return0;
}
POJ2811熄燈問題
題目描述 事實上,只用列舉第一行或者第一列按鈕的狀態即可。下面以列舉第一行按鈕的狀態為例。因為第一行燈的狀態由第一行和第二行的按鈕決定,所以第一行按鈕的狀態確定之後,為是第一行的燈全部熄滅,第二行按鈕的狀態也就唯一確定了。例如,當第一行按鈕的狀態確定之後 因此,在第一行按鈕的狀態確定之後,第二行按鈕...
POJ 2811 熄燈問題 POJ 1222
樣例輸入 輸出後面有 區域性即整體思想 雖然整體情況看起來巨多,眼花繚亂,但有時候問題的一小部分,其實對應了所有的結果,因為所有的結果都是從這一區域性出發生長出來的 雞湯 細節決定成敗,丟了馬蹄鐵導致戰爭失敗 本題 第一行就是這樣的 區域性 任意給出乙個第一行的按開關方案,後面所有行,要想成功,一定...
2811 熄燈問題(列舉)
描述有乙個由按鈕組成的矩陣,其中每行有6個按鈕,共5行。每個按鈕的位置上有一盞燈。當按下乙個按鈕後,該按鈕以及周圍位置 上邊 下邊 左邊 右邊 的燈都會改變一次。即,如果燈原來是點亮的,就會被熄滅 如果燈原來是熄滅的,則會被點亮。在矩陣角上的按鈕改變3盞燈的狀態 在矩陣邊上的按鈕改變4盞燈的狀態 其...