zoukankan      html  css  js  c++  java
  • POJ 1830 开关问题


    简单的高斯消元取模,答案为2^自由变元的数量,可是题目的意思把I,J搞反了,坑爹。

    。。


    开关问题
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 5425   Accepted: 2023

    Description

    有N个同样的开关。每一个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其它的与此开关相关联的开关也会对应地发生变化,即这些相联系的开关的状态假设原来为开就变为关。假设为关就变为开。

    你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态。

    对于随意一个开关。最多仅仅能进行一次开关操作。

    你的任务是。计算有多少种能够达到指定状态的方法。(不计开关操作的顺序)

    Input

    输入第一行有一个数K。表示下面有K组測试数据。 
    每组測试数据的格式例如以下: 
    第一行 一个数N(0 < N < 29) 
    第二行 N个0或者1的数,表示開始时N个开关状态。

     
    第三行 N个0或者1的数。表示操作结束后N个开关的状态。 
    接下来 每行两个数I J,表示假设操作第 I 个开关,第J个开关的状态也会变化。每组数据以 0 0 结束。

     

    Output

    假设有可行方法,输出总数。否则输出“Oh,it's impossible~!!” 不包含引號

    Sample Input

    2
    3
    0 0 0
    1 1 1
    1 2
    1 3
    2 1
    2 3
    3 1
    3 2
    0 0
    3
    0 0 0
    1 0 1
    1 2
    2 1
    0 0
    

    Sample Output

    4
    Oh,it's impossible~!!
    

    Hint

    第一组数据的说明: 
    一共下面四种方法: 
    操作开关1 
    操作开关2 
    操作开关3 
    操作开关1、2、3 (不记顺序) 

    Source

    [Submit]   [Go Back]   [Status]   [Discuss]



    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn=50;
    int equ,var;
    int a[maxn][maxn],x[maxn];
    int free_x[maxn],free_num;
    
    int Gauss()
    {
    	int max_r,col,k;
    	free_num=0;
    	for(k=0,col=0;k<equ&&col<var;k++,col++)
    	{
    		max_r=k;
    		for(int i=k+1;i<equ;i++)
    		{
    			if(abs(a[i][col])>abs(a[max_r][col]))
    				max_r=i;
    		}
    		if(a[max_r][col]==0)
    		{
    			k--;
    			free_x[free_num++]=col;
    			continue;
    		}
    		if(max_r!=k)
    		{
    			for(int j=col;j<var+1;j++)
    				swap(a[k][j],a[max_r][j]);
    		}
    		for(int i=k+1;i<equ;i++)
    		{
    			if(a[i][col]!=0)
    			{
    				for(int j=col;j<var+1;j++)
    					a[i][j]^=a[k][j];
    			}
    		}
    	}
    	for(int i=k;i<equ;i++)
    		if(a[i][col]!=0)
    			return -1;
    	if(k<var) return var-k;
    	for(int i=var-1;i>=0;i--)
    	{
    		x[i]=a[i][var];
    		for(int j=i+1;j<var;j++)
    			x[i]^=(a[i][j]&&x[j]);
    	}
    	return 0;
    }
    		
    
    
    int begin[40],end[40],n;
    
    int main()
    {	
    	int T_T;
    	scanf("%d",&T_T);
    	while(T_T--)
    	{
    		memset(a,0,sizeof(a));
    		memset(x,0,sizeof(x));
    		scanf("%d",&n);
    		equ=var=n;
    		for(int i=0;i<n;i++)
    			scanf("%d",begin+i);
    		for(int i=0;i<n;i++)
    			scanf("%d",end+i);
    		for(int i=0;i<n;i++)
    			a[i][n]=begin[i]^end[i],a[i][i]=1;
    		int n1,n2;
    		while(scanf("%d%d",&n1,&n2)!=EOF)
    		{
    			if(n1==0&&n2==0) break;
    			n1--; n2--;
    			a[n2][n1]=1;
    		}
    		int t=Gauss();
    		if(t==-1)
    		{
    			puts("Oh,it's impossible~!!");
    			continue;
    		}
    		printf("%d
    ",1<<t);
    	}
    	return 0;
    }
    



  • 相关阅读:
    【XSY2990】树 组合数学 容斥
    【LOJ2542】【PKUWC 2018】随机游走 min-max容斥 树上高斯消元
    【51NOD1847】奇怪的数学题 min_25筛
    【51NOD1965】奇怪的式子 min_25筛
    蒟蒻的学习计划
    【XSY2962】作业 数学
    蒟蒻的做题记录
    【LOJ2586】【APIO2018】选圆圈 CDQ分治 扫描线 平衡树
    【APIO2016】【UOJ205】【LOJ2568】烟花表演 可合并堆
    【BZOJ2876】【Noi2012】骑行川藏 拉格朗日乘法
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6917602.html
Copyright © 2011-2022 走看看