POJ 開關問題 解題報告

2022-04-30 03:36:12 字數 1601 閱讀 7830

有n個相同的開關,每個開關都與某些開關有著聯絡,每當你開啟或者關閉某個開關的時候,其他的與此開關相關聯的開關也會相應地發生變化,即這些相聯絡的開關的狀態如果原來為開就變為關,如果為關就變為開。你的目標是經過若干次開關操作後使得最後n個開關達到乙個特定的狀態。對於任意乙個開關,最多只能進行一次開關操作。你的任務是,計算有多少種可以達到指定狀態的方法。(不計開關操作的順序)

輸入第一行有乙個數k,表示以下有k組測試資料。

每組測試資料的格式如下:

第一行 乙個數n(0 < n < 29)

第二行 n個0或者1的數,表示開始時n個開關狀態。

第三行 n個0或者1的數,表示操作結束後n個開關的狀態。

接下來 每行兩個數i j,表示如果操作第 i 個開關,第j個開關的狀態也會變化。每組資料以 0 0 結束。

output

如果有可行方法,輸出總數,否則輸出「oh,it's impossible~!!」 不包括引號23

0 0 0

1 1 1

1 21 3

2 12 3

3 13 2

0 03

0 0 0

1 0 1

1 22 1

0 04

oh,it's impossible~!!

第一組資料的說明:

一共以下四種方法:

操作開關1

操作開關2

操作開關3

操作開關1、2、3 (不記順序)

參考lyd的演算法競賽高階指南。

設\(a_\)代表\(j\)操作後是否影響\(i\),\(x_i\)為第\(i\)個開關是否操作

\(\begin

a_*x_1 & xor & a_*x_2 & ... & a_*x_n & to_1 \\

a_*x_1 & xor & a_*x_2 & ... & a_*x_n & to_2 \\

...\\

a_*x_1 & xor & a_*x_2 & ... & a_*x_n & to_n \\

\end\quad\)

異或就是不進製加法,我們參照著普通的高斯消元做就可以了

最後解的個數是1《自由元的數量

用狀態壓縮儲存一行狀態,可以做到n^2

然而書中是這樣寫的

for(int i=1;i<=n;i++)

if(!a[i])

而我強行

int r=n+1-i;

if(a[i]>>r&1)

for(int j=i+1;j<=n;j++)

if(a[j]>>r&1) a[j]^=a[i];

自然是wa掉啦,原因列指標並不一定等於行指標

不過這樣就行啦(這時候ans不是答案,是自由元個數)

for(int i=1;i<=n;i++)

if(!a[i])

int r=n+1-i;

if(!(a[i]>>r&1)) ++ans;

for(int j=i+1;j<=n;j++)

if(a[j]>>r&1) a[j]^=a[i];

}

2018.8.29

poj3984迷宮問題解題報告

問題描述 迷宮問題 time limit 1000ms memory limit 65536k total submissions 3577 accepted 2093 description 定義乙個二維陣列 int maze 5 5 它表示乙個迷宮,其中的1表示牆壁,0表示可以走的路,只能橫著走...

POJ 1321 棋盤問題解題報告

棋盤問題 time limit 1000ms memory limit 10000k total submissions 13737 accepted 6786 description 在乙個給定形狀的棋盤 形狀可能是不規則的 上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一...

石子問題解題報告

description 有兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。遊戲規定,每次有兩種不同的取法,一是可以在任意的一堆中取走任意多的石子 二是可以在兩堆中同時取走相同數量的石子。最後把石子全部取完者為勝者。現在給出初始的兩堆石子的數目,如果輪到你先取,假設雙方都採取最好的策略,問最...