zoukankan      html  css  js  c++  java
  • 开关问题(高斯消元,异或方程组)

    POJ

    有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开.你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态.对于任意一个开关,最多只能进行一次开关操作/算有多少种可以达到指定状态的方法?(不计开关操作的顺序)

    分析:设(x_1=1(0))表示(没)开了这个开关,(a_{i,j}=1(0))表示(i,j)这两个开关有(无)联系,则(a_{i,i}=1).

    (a_{1,1}x_1xora_{1,2}x_2xor...xora_{1,n}x_n=)初状态xor末状态(很好理解:只有同时满足 开关j影响i 且 j开了 这两个条件,才会对i的状态产生影响)

    以此类推可以得到n个这样的方程,构成异或方程组.然后直接高斯消元即可.

    我们还可以把一个方程状态压缩为一个int型整数.

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline LL read(){
        LL s=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
        return s*w;
    }
    int a[105];
    int main(){
        int T=read();
        while(T--){
    		int n=read();
    		for(int i=1;i<=n;i++)a[i]=read();
    //第i个开关的初状态
    		for(int i=1;i<=n;i++){
    	    	int j=read();//读入第i个开关的末状态
    	    	a[i]^=j;//方程组的右边:初状态xor末状态
                a[i]|=1<<i;//状态压缩:a[i][i]=1
    		}
    		while(1){
    	    	int x=read(),y=read();//x影响y
    	    	if(x==0&&y==0)break;
    	    	a[y]|=1<<x;//状态压缩:a[y][x]=1
    		}
    		int ans=1;
    		for(int i=1;i<=n;i++){
    	    	for(int j=i+1;j<=n;j++)
    				if(a[j]>a[i])swap(a[i],a[j]);
    //找到最大的一个a[i],即主元位数最高的a[i]
    	    	if(a[i]==0){ans=1<<(n-i+1);break;}
    //0=0,消元完毕,有i-1个主元,n-i+1个自由元
    	    	if(a[i]==1){ans=0;break;}
    //1=0,方程无解
    //用a[i]去消其它方程
    	    	for(int k=n;k;k--)
    				if((a[i]>>k)&1){//从高位到低位,找为1的那一位
    		    		for(int j=1;j<=n;j++)
    						if(i!=j&&((a[j]>>k)&1))a[j]^=a[i];
    //如果第j个方程的这一位也是1,则可以把它消去
    		    	    break;
    				}
    		}
    		if(ans==0)puts("Oh,it's impossible~!!");
    		else printf("%d
    ",ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    mysql读写分离
    mysql主从同步
    mysql修改密码
    mysql单机安装以及语法,alter表
    zabbix主动监控
    数据集
    K-近邻算法
    常规套路
    区分子类方法中重名的三种变量
    Java的数学工具类Math
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10604033.html
Copyright © 2011-2022 走看看