POJ 2811 熄燈問題 列舉

2021-10-03 20:35:30 字數 3920 閱讀 6780

總時間限制: 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盞燈的狀態 其...