1. 程式人生 > >POJ.1830.開關問題(高斯消元)

POJ.1830.開關問題(高斯消元)

高斯 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.開關問題(高斯消元)