洛谷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的話,如果這盞燈是關的,那麼把它...