POJ1830 開關問題 Gauss消元

2021-08-16 10:39:49 字數 2697 閱讀 5520

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

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

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

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

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

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

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

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

2

30 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 0

4

oh,it's

impossible~!

!

第一組資料的說明:

一共以下四種方法:

操作開關1

操作開關2

操作開關3

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

首先根據燈泡的起始狀態和末尾狀態可以確定出某個燈泡變換的次數%2的值 即最終效果是變還是不變

這樣未知數[x

1,x2

,...

,xn]

[ x1

,x2,

...,

xn

]表示初始狀態

對於係數矩陣 其表示:行號表示的某個開關會被哪些燈影響,會影響的賦1,其餘賦0 對角線賦1⎡⎣

⎢a11a

21a31a

12a22a

32a13a

23a33⎤

⎦⎥[ a11

a12a13

a21a22

a23a31

a32a33

]而經過乘法組合和右邊的值就為初始末尾異或值

即求解 ⎡⎣

⎢a11a

21a31a

12a22a

32a13a

23a33⎤

⎦⎥∗⎡

⎣⎢x1

x2x3

⎤⎦⎥=

⎡⎣⎢⎢

⎢初末異

或⎤⎦⎥

⎥⎥[ a11

a12a13

a21a22

a23a31

a32a33

]∗[x

1x2x

3]=[

初末異或

]ans為自由

變元的個

數2自由

變元的個

數 自由變元

的個數2

自由變元

的個

數為什麼這樣的可行呢?

因為在%2意義下行變換方程自由變元的個數是一樣的 (和不%2相比)

所以不需考慮%2

因為2是質數?

//高斯消元 時間複雜度o(n^3) 使用浮點數計算

#include

#include

#include

using

namespace

std;

const

double eps=1e-8;

const

int maxn=101;

//也可以避免實數運算 使用輾轉相減的方法 多乙個log的時間複雜度

//特別適合於行列式求值 取模操作 (除法要求逆元)

int solve(double a[maxn],bool l,double ans,const

int &n,const

int &m)

//從a[r][i]這乙個元素開始 往下的每個元素都是0了 所以這個元素xi是自由變元 i+1跳過即可

if(fabs(a[r][i])continue;

}for(int j=0;j//j是行數 從第一行(j=0)開始 讓上三角更簡潔 這樣後面求ans就沒有必要從下往上了

if(j!=r && fabs(a[j][i])>eps)

l[i]=true,++r;

}//檢查是否無解

for(int i=n-res;iif(fabs(a[i][n])>eps) return -1;

}//下面求結果

for(int i=0;iif(l[i])//不是自由變元

for(int j=0;jif(fabs(a[j][i])>eps)

ans[i]=a[j][n]/a[j][i];

return res;//返回自由變元數

}int main()

res=solve(a,l,ans,n,m);

if(res==-1) cout

<<"oh,it's impossible~!!"

cout

<<(1

0;}

POJ1830 開關問題

中文題目,就不說題目大意了 解題思路 由於對於每乙個開關最多改變一次,那麼對於每乙個開關,只有改變與不改變兩種操作,設改變操作為1,不改變操作為0,那麼對開關的操作可以用乙個n維向量x t x 1,x2 x n 其中xi 0或者 1 我們需要知道初始狀態經過某次操作之後的狀態,並拿它與目標狀態比較。...

開關問題 POJ 1830

題意 燈泡對應開關,有些開關的撥動會影響其他的開關,給出燈泡初始狀態,給出燈泡結束狀態,問有幾種操作可以完成 思路 建立矩陣,消元後有n個自由變元,答案就是2 n個 include include include includeusing namespace std const int maxn 5...

POJ 1830 開關問題

前述 今天又領略了被假模版坑的心痛,基本都在調 由於被問及相關poj 1222的異或方程組的相關問題,我總算是知道了昨天那個博主為什麼理解了兩天了.原來poj 1222的相關題解都是用矩陣講的異或方程組,講的賊煩,而我正好找了乙個類似卻又不存在的題目,用他的 a了這個poj 1222,渾然不知有這等...