首页 > 其他 > 详细

POJ 1830 开关问题

时间:2019-09-04 22:45:24      阅读:59      评论:0      收藏:0      [点我收藏+]

怕不是今天刚会写异或高斯消元。。还是抄的lyd的


思路:异或高斯消元

提交:1次

题解:

若解唯一,答案为1
无解即出现系数矩阵为0,但增广矩阵为1
有自由元即一整行都是0,此时答案为 \(2^{\texttt{自由元的数量}}\)

#include<iostream>
#include<cstdio>
#define ll long long 
#define R register int
using namespace std;
namespace Luitaryi {
inline ll g() { R x=0,f=1;
  register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
  do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
} int T,n,a[30];
inline int Gauss() {
  for(R i=1;i<=n;++i) {
    for(R j=i+1;j<=n;++j) if(a[j]>a[i]) swap(a[i],a[j]);
    if(a[i]==0) return 1<<(n-i+1);//2^(自由元的数量)
    if(a[i]==1) return -1;//增广矩阵是1,然而系数全是0 
    for(R k=n;k;--k) if(a[i]&(1<<k)) {//若从高位看,第k位是有系数的 
      for(R j=1;j<=n;++j) if(i!=j&&a[j]&(1<<k)) //若a[j][k]==1,即可以进行异或运算 
        a[j]^=a[i]; 
      break;
    }
  } return 1;
}
inline void main() {
  T=g(); while(T--) {
    n=g(); for(R i=1;i<=n;++i) a[i]=g();
    for(R i=1,x;i<=n;++i) x=g(),a[i]^=x,a[i]|=1<<i;
    R x,y,ans; while(x=g(),y=g(),x&&y) a[y]|=1<<x;//可以由x传到y 
    ans=Gauss(); if(ans>0) printf("%d\n",ans);
    else puts("Oh,it's impossible~!!");
  }
}
} signed main() {Luitaryi::main(); return 0;}

2019.09.04
65

POJ 1830 开关问题

原文:https://www.cnblogs.com/Jackpei/p/11461604.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!