poj 1830 開關問題(高斯消元)

2021-06-18 13:18:02 字數 1366 閱讀 9081

終止狀態是從初始狀態由開關組合影響而形成的,那麼就有乙個等式使得初始狀態可以到達終止狀態,

例如a,b,c三個開關

e[a] = (xa * mp[a][a]) ^ (xb * mp[a][b]) ^ (xc*map[a][c]) ^ s[a]

e[b] = (xa * mp[b][a]) ^ (xb * mp[b][b]) ^ (xc*map[b][c]) ^ s[b]

e[c] = (xa * mp[c ][a]) ^ (xb * mp[c][b]) ^ (xc*map[c][c]) ^ s[c]

e陣列為開關的終止狀態(a,b,c為開關),s陣列為開關的初始狀態,mp[i][j] 代表j開關是否影響i開關。x為變元

根據上面的方程裝換成高斯方程組

換成矩陣形式:

mp[a][a]   mp[a][b]   map[a][c]    e[a ]^ s[a]

mp[b][a]   mp[b][b]   map[b][c]    e[b] ^ s[b]

mp[c ][a]   mp[c][b]   map[c][c]    e[c] ^ s[c ]

轉換成行階梯型矩陣,然後求出矩陣的秩,矩陣的秩即為不變元的個數,剩下的就是自由元的個數。

不變元就是,我們將開關由初始狀態變為終止狀態所必須要動的開關,而自由元就是我們不一定要動的開關。

因此,我們能到達終止狀態的方案就是2的自由元次冪的個數,因為每個開關只有0,1兩種狀態。

注意求解是異或運算。

#include #include #include #include using namespace std;

#define maxn 50

int a[maxn], e[maxn];

int n;

void swap(int &a,int &b)

struct matrix

}void relax(int x, int y)

}void init()

}}m;void gauss()

}if(ptr == n+1)

if(ptr != i)

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

m.relax(i,k);//不是,則消除。}}

for( k = i; k <= n; k++)

}printf("%d\n",1<<(n-i+1));//有多少零行就有多少自由元,輸出結果

return;

}int main()

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

while(scanf("%d%d",&s,&t),s|t)

gauss();

}return 0;

}

POJ 1830 開關問題 高斯消元

開關問題 time limit 1000ms memory limit 30000k total submissions 3390 accepted 1143 description 有n個相同的開關,每個開關都與某些開關有著聯絡,每當你開啟或者關閉某個開關的時候,其他的與此開關相關聯的開關也會相應...

poj 1830 開關問題 高斯消元

題意是 給一些開關的初始狀態 0 或1 在給出終止狀態,在給出相關的變化規則,規則 x 變化 則 y 也變 x y 讀入。輸出有多少種開關的撥動情況,使初始狀態變成終止狀態。此問題 很容易轉化成 高斯消元 解 異或方程組。t 方程組的自由化的個數,則結果就是 2 t include include ...

poj 1830 開關問題 高斯消元

題意 給出一些開關互相影響的關係,問從開關的初始狀態到結束狀態有多少種變換的方法。題解 對於每個開關可能會受1.i某寫開關的影響,因此對於開關i列出乙個列向量,列向量每個元素只有1或0,表示某個開關是否影響這個i開關,這樣就n個開關組合成乙個矩陣,結束狀態也是乙個列向量,這樣就可以用高斯消元求解解的...