洛谷關燈問題2

2021-09-10 19:14:55 字數 1673 閱讀 1156

題目描述

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

現在這些燈都是開的,給出所有開關對所有燈的控制效果,求問最少要按幾下按鈕才能全部關掉。

輸入輸出格式

輸入格式:

前兩行兩個數,n m

接下來m行,每行n個數,a[i][j]表示第i個開關對第j個燈的效果。

輸出格式:

乙個整數,表示最少按按鈕次數。如果沒有任何辦法使其全部關閉,輸出-1

輸入輸出樣例

輸入樣例#1: 複製32

1 0 1

-1 1 0

輸出樣例#1: 複製2說明

對於20%資料,輸出無解可以得分。

對於20%資料,n<=5

對於20%資料,m<=20

上面的資料點可能會重疊。

對於100%資料 n<=10,m<=100

使用dp 將問題所列的狀態用二進位制數來表示

1 表示燈開

0 表示燈關

列舉m個開關的狀態

以燈全開為起點進行列舉操作

《手打可能有誤

異或,與,或,好重要~(up up up

for

(int i=

1;i<=m;i++

)}

**~~ 感謝

ss&(1<< j-1)此運算用以檢查當前狀態的第j位是否為1

1<< j-1意思是將1左移j-1位,移動後只有第j位上是1

若開關操作為1且當前狀態第j位是1

則ss^=(1<< j-1) 表示 1與1異或後得0

若開關操作為-1且當前狀態第j位是0

則ss|=(1 << j-1) 表示 1或0 後得1 (此處異或操作也對,因為1異或0得1)

之後便用相同的方法在得到的每個狀態上再不斷搜尋每個狀態

由於是bfs,所以一旦某一步狀態表示為0(十進位制二進位制的0寫法都是0)

則當前步數必定是最短運算元

若遍歷完所有狀態都沒有0,則輸出-1

記得搜尋過的狀態要打vis標記避免重複訪問

#include

#include

#include

using

namespace std;

int n,m,cz[

150][20

];int vis[

1<<11]

;struct node

;int

bfs())

; vis[(1

<]=1;

int i,j;

while

(!q.

empty()

)int k;

for(i=

1;i<=m;i++)if

(!vis[k]))

;}}}

return-1

;}intmain()

}printf

("%d"

,bfs()

);}

第一次寫dp類的bfs ~

加油panda

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

洛谷p2622 關燈問題

乙個比較典型的狀態壓縮演算法,不過現在還有點沒看懂。等留著以後再看.include include include include include includeusing namespace std int read while ss 0 ss 9 return f x void print in...