洛谷 P2622 關燈問題II

2021-08-21 12:26:40 字數 1163 閱讀 6181

洛谷p2622

tag:狀態壓縮

【題目大意】

n個燈,m個按鈕,每個按鈕都可以控制所有燈,給出每個按鈕對每個燈的影響,求從全開到全關的最短步數。

【題目分析】

每盞燈只有兩個狀態,即開與關,記為0和1,則所有燈的狀態總數為2^n(n=3時,有000,001,010,100……)

對每個狀態單獨分析,可以把每個開關看作一條有向邊,這樣把不同的狀態連起來(也可能出現自環),因此,此題就變成了最短路問題,可以廣搜解決。

接下來要考慮的是如何將按鈕變成邊,即如何確定經過按鈕的操作,當前狀態將轉變成哪個狀態。

回想二進位制操作(與、或、非、抑或),經過嘗試,我們發現「與」操作可以幫助我們解決關燈問題。比如:當原狀態為100時(1表示開燈,0關),按鈕1可以讓1和3號燈關上,我們就可以令按鈕1等於010.

100&010=000

「或」操作可以解決開燈問題,如:原狀態為110,按鈕2可以讓1和3開啟

110|101=111

當按鈕3可以讓1和3關上,讓2開啟時,就可以與010,或010,順序不會影響結果。

【**實現】

將二進位制直接放到陣列裡?這是不現實的,所以還是用十進位制來實現。

如何提取其中的一位呢?

a & (1《表示提取a的第j位,若結果是0,說明為0,若結果不為0,說明是1。

標程

#include//2622

using namespace std;

int n , m , state[1200];//n<=10,所以前1023是有用的 表示到達i狀態需要走的步數

int trans[1200][105]; //trans[i][j]表示對狀態i按下按鈕j的狀態

int q[1200000],now;//q代表即將處理的佇列

int temp,open[110],close[110];

int main()

for( int i = 0 ; i < (1

trans[i][j] = ( i & close[j] ) | open[j];//經過按鈕j,i會變成trans[i][j]

while( l <= r )

} } cout

}

洛谷 P2622 關燈問題II

現有n盞燈,以及m個按鈕。每個按鈕可以同時控制這n盞燈 按下了第i個按鈕,對於所有的燈都有乙個效果。按下i按鈕對於第j盞燈,是下面3中效果之一 如果a i j 為1,那麼當這盞燈開了的時候,把它關上,否則不管 如果為 1的話,如果這盞燈是關的,那麼把它開啟,否則也不管 如果是0,無論這燈是否開,都不...

洛谷 P2622 關燈問題II

洛谷傳送門 現有n盞燈,以及m個按鈕。每個按鈕可以同時控制這n盞燈 按下了第i個按鈕,對於所有的燈都有乙個效果。按下i按鈕對於第j盞燈,是下面3中效果之一 如果a i j 為1,那麼當這盞燈開了的時候,把它關上,否則不管 如果為 1的話,如果這盞燈是關的,那麼把它開啟,否則也不管 如果是0,無論這燈...

洛谷 P2622 關燈問題

輸入輸出樣例 說明切入正題 解 廣搜 手動分割 現有n盞燈,以及m個按鈕。每個按鈕可以同時控制這n盞燈 按下了第i個按鈕,對於所有的燈都有乙個效果。按下i按鈕對於第j盞燈,是下面3中效果之一 如果a i j 為1,那麼當這盞燈開了的時候,把它關上,否則不管 如果為 1的話,如果這盞燈是關的,那麼把它...