POJ1830 異或方程組的高斯消元

2021-06-19 17:27:19 字數 2144 閱讀 8838

對於式子(((a^b)^b)^b)……,即a對b進行連續異或時,可以發現有如下規律:

若b為1,式子的值會在每次異或之後取反,因為0^1=1,1^1=0,……

若b為0,式子的值會保持a值不變,因為0^0=0,1^0=1,……

因而這種性質可以利用在poj1830這樣的有關聯的開關問題上:(每個開關只能改變一次)

假設開關1和開關2、3相關聯,且開關1的初始狀態為0,終態為1,。

用1表示該開關被改變過,0表示未被改變。

則開關1到達終態的情況可能有:①只改變開關1   ②改變開關1、2、3

則對應的異或式子為  ①((1^0)^0)=1  ②((1^1)^1)=1。

同樣的對於開關2和開關3可以列出相應的式子,此時將開關是否被操作過設定為變數x1,x2,x3。

列出3條方程組,等式右邊1表示與初始狀態不同,0表示與初始狀態相同。

解的數目即為到達終態的情況數目,每組解對應著乙個開關操作情況。

對於題目的第乙個測試用例列出的異或方程為

①x1^x2^x3=1

②x1^x2^x3=1

③x1^x2^x3=1

可求出自由變數有2個,則情況總數為1<<2=4。

對於求解異或方程組,和普通的加減方程組是一樣的,只需要將加減操作換成異或操作,高斯消元化簡後求出自由變數的數目。

第二個測試用例列出的矩陣為

1 1 0 1         1 1 0 1

1 1 0 0   →  0 0 0 1            可看到第二行為無解的情況。

0 0 1 1         0 0 1 1

#include #include #include using namespace std;

int a[35][35];

int b[35];

int n;

int ans;

void swap(int a,int b)

temp=b[a];

b[a]=b[b];

b[b]=temp;

}void gauss()

}if (!flag) continue;

} for (j=i+1;j<=n-1;j++)

}} for (i=n-1;i>=0;i--)

else if (a[i][i]==0)

ans=ans<<1;

else

}} }

}int main()

memset(a,0,sizeof(a));

for (i=0;i<=n-1;i++)

a[i][i]=1;

while (1)

gauss();

if (ans!=-1)

printf("%d\n",ans);

else

printf("oh,it's impossible~!!\n");

} return 0;

}

異或方程組的高斯消元模板:

//有equ個方程,var個變元。增廣矩陣行數為equ,列數為var+1,分別為0到var

int equ,var;

int a[maxn][maxn]; //增廣矩陣

int x[maxn]; //解集

int free_x[maxn];//用來儲存自由變元(多解列舉自由變元可以使用)

int free_num;//自由變元的個數

//返回值為-1表示無解,為0是唯一解,否則返回自由變元個數

int gauss()

if(a[max_r][col] == 0)

if(max_r != k)

for(int i = k+1;i < equ;i++)}}

for(int i = k;i < equ;i++)//進入此迴圈的條件:本身矩陣行大於列 或者 因為出現自由變元後使得非自由變元數比行數小

if(a[i][col] != 0)//若等號右邊是1則無解,因為等號左邊已經消為0

return -1;//無解

if(k < var) return var-k;//自由變元個數

//唯一解,回代

for(int i = var-1; i >= 0;i--)

return 0;

}

poj 1830 異或方程組

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

POJ1830 開關問題(異或方程組)

本作品採用知識共享署名 相同方式共享 4.0 國際許可協議進行許可。有n個相同的開關,每個開關都與某些開關有著聯絡,每當你開啟或者關閉某個開關的時候,其他的與此開關相關聯的開關也會相應地發生變化,即這些相聯絡的開關的狀態如果原來為開就變為關,如果為關就變為開。你的目標是經過若干次開關操作後使得最後n...

POJ 1830 開關問題 高斯消元 異或方程組

自由元有兩種取值而且相互不影響,乘法定理可得 include include include using namespace std define for i,j,k for i j i k i define rep i,j,k for i j iconst int dx const int dy ...