POJ.1830.開關問題(高斯消元)
阿新 • • 發佈:2018-02-13
高斯 http lin ctype fin tin 一行 行數 str
題目鏈接
顯然我們需要使每個i滿足\(( ∑_{j} X[j]*A[i][j] ) % 2 = B[i]\)
求這個方程自由元Xi的個數ans,那麽方案數便是\(2^{ans}\)
%2可以用^代替,不難看出 B[i]=st[i]^ed[i]
如果X[j]=1,假設j會影響i,那麽X[j]*A[i][j]這一項應為1,所以A[i][j]應=1 輸入別反!
註意A[i][i]=1
將系數矩陣化為上三角形式後,剩下的系數全為0的行數就是自由元的個數;
如果某一行系數全為零,增廣矩陣最後一列對應行的值不為0,則無解
//硬是被輸入反了坑了半天。。
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
const int N=31;
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
struct Gauss
{
int n;
bool A[N][N];
void Init()
{
memset(A,0,sizeof A);
n=read();
for(int i=0; i<n; ++i) A[i][n]=read();
for(int i=0; i<n; ++i) A[i][n]^=read();
for(int i=0; i<n; ++i) A[i][i]=1;
int a,b;
while(a=read(),b=read(),a&&b) A[b-1 ][a-1]=1;//a,b別反!
}
void Solve()
{
int r=0,c=0;
while(r<n && c<n)
{
int mxrow=r;
for(int i=r+1; i<n; ++i)
if(A[i][c]>A[mxrow][c]) mxrow=i;
if(!A[mxrow][c]) {++c; continue;}
if(mxrow!=r) std::swap(A[r],A[mxrow]);
for(int i=r+1; i<n; ++i)
if(A[i][c])
for(int j=c; j<=n; ++j)
A[i][j]^=A[r][j];
++r, ++c;
}//從r往後的行的矩陣元素都為0
for(int i=r; i<n; ++i)//某一行系數全為0但最後一列不為0
if(A[i][n]) {puts("Oh,it's impossible~!!"); return;}
printf("%d\n",1<<(n-r));
}
}g;
int main()
{
int t=read();
while(t--) g.Init(), g.Solve();
return 0;
}
POJ.1830.開關問題(高斯消元)