• POJ.1830.开关问题(高斯消元 异或方程组)


    题目链接
    显然我们需要使每个i满足$$( ∑_{j} X[j]A[i][j] ) mod 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
    ",1<<(n-r));
    	}
    }g;
    
    int main()
    {
    	int t=read();
    	while(t--) g.Init(), g.Solve();
    	return 0;
    }
    
  • 相关阅读:
    eclipse如何卸载adt插件
    Android中的Toast.LENGTH_SHORT
    Frogger
    - Oil Deposits 深搜,就是所谓的dfs
    Aggressive cows
    Phone List
    Word Amalgamation
    Street Numbers
    Charm Bracelet——背包问题
    函数参考
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8445969.html
Copyright © 2020-2023  润新知