开关问题
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 8714   Accepted: 3424

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 (不记顺序) 

题目链接:POJ 1830

比较裸的一道题,记得开关自己跟自己是有关系的,即Mat[i][i]要恒为1,用高斯消元在判断了自由变量之后如果还出现非0系数,则说明无解,如果有解即有$freenum$个自由变量,那么显然每一个自由变量是随意取值的,每一个都取0或1,那么答案显然是$2^{freenum}$个

如何列方程呢?两边同时异或一下开始的状态即可以得到目标的状态,因为S->T的操作和0->(S xor T)的操作是一样的

代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#include <numeric>
#include <cstring>
#include <bitset>
#include <string>
#include <deque>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 31;
int Mat[N][N]; int Gaussian(int ne, int nv)
{
int ce, cv, i, j;
for (ce = 1, cv = 1; ce <= ne && cv <= nv; ++ce, ++cv)
{
int te = ce;
for (i = ce + 1; i <= ne; ++i)
if (Mat[i][cv] > Mat[te][cv])
te = i;
if (te != ce)
{
for (i = cv; i <= nv + 1; ++i)
swap(Mat[ce][i], Mat[te][i]);
}
if (!Mat[ce][cv])
{
--ce;
continue;
}
for (i = ce + 1; i <= ne; ++i)
{
if (Mat[i][cv])
{
for (j = cv; j <= nv + 1; ++j)
Mat[i][j] ^= Mat[ce][j];
}
}
}
for (i = ce; i <= ne; ++i)
if (Mat[i][cv])
return -1;
return nv - (ce - 1);
}
int main(void)
{
int tcase, n, i;
scanf("%d", &tcase);
while (tcase--)
{
CLR(Mat, 0);
scanf("%d", &n);
for (i = 1; i <= n; ++i)
{
scanf("%d", &Mat[i][n + 1]);
Mat[i][i] = 1;
}
for (i = 1; i <= n; ++i)
{
int x;
scanf("%d", &x);
Mat[i][n + 1] ^= x;
}
int a, b;
while (~scanf("%d%d", &a, &b) && (a || b))
Mat[b][a] = 1;
int frnum = Gaussian(n, n);
frnum == -1 ? puts("Oh,it's impossible~!!") : printf("%d\n", 1 << frnum);
}
return 0;
}

POJ 1830 开关问题(高斯消元求解的情况)的更多相关文章

  1. POJ 1830 开关问题 高斯消元,自由变量个数

    http://poj.org/problem?id=1830 如果开关s1操作一次,则会有s1(记住自己也会变).和s1连接的开关都会做一次操作. 那么设矩阵a[i][j]表示按下了开关j,开关i会被 ...

  2. POJ 1830 开关问题 (高斯消元)

    题目链接 题意:中文题,和上篇博客POJ 1222是一类题. 题解:如果有解,解的个数便是2^(自由变元个数),因为每个变元都有两种选择. 代码: #include <iostream> ...

  3. POJ 1830 开关问题 [高斯消元XOR]

    和上两题一样 Input 输入第一行有一个数K,表示以下有K组测试数据. 每组测试数据的格式如下: 第一行 一个数N(0 < N < 29) 第二行 N个0或者1的数,表示开始时N个开关状 ...

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

    题目链接 显然我们需要使每个i满足\[( ∑_{j} X[j]*A[i][j] ) mod\ 2 = B[i]\] 求这个方程自由元Xi的个数ans,那么方案数便是\(2^{ans}\) %2可以用^ ...

  5. 【poj1830-开关问题】高斯消元求解异或方程组

    第一道高斯消元题目~ 题目:有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关 ...

  6. 【poj2947】高斯消元求解同模方程组【没有AC,存代码】

    题意: p start enda1,a2......ap (1<=ai<=n)第一行表示从星期start 到星期end 一共生产了p 件装饰物(工作的天数为end-start+1+7*x, ...

  7. 【zoj3645】高斯消元求解普通线性方程

    题意: 给你一个方程组(含有12个方程),求(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11) 方程组的形式是一个二次方程组 (ai1-x1)^2 + (ai2-x2)^2 +( ...

  8. POJ 1222 POJ 1830 POJ 1681 POJ 1753 POJ 3185 高斯消元求解一类开关问题

    http://poj.org/problem?id=1222 http://poj.org/problem?id=1830 http://poj.org/problem?id=1681 http:// ...

  9. POJ 3185 The Water Bowls 【一维开关问题 高斯消元】

    任意门:http://poj.org/problem?id=3185 The Water Bowls Time Limit: 1000MS   Memory Limit: 65536K Total S ...

随机推荐

  1. 【HDU1542】Atlantis (扫描线的经典运用)

    点此看题面 大致题意: 给你\(N\)个矩形,请你求出它们覆盖的面积(重叠的面积只算一次). 扫描线 这道题是一道典型的求矩形面积并问题,是扫描线的一个经典运用.这里就不赘述了. 代码 #includ ...

  2. 创建一个 Dynamic Web Project

    准备工作 一.修改 JDK Compliance level 二.创建 Dynamic Web Project Ctrl + N 三.配置网站服务器 tomcat 这里切记不要点击 Finish ,一 ...

  3. 数据结构-二分查找(Binary Search)

    #include <stdio.h> #include <string.h> #include <stdlib.h> #define LIST_INIT_SIZE ...

  4. scrapy框架简介和基础使用

    概念 为了爬取网站数据而编写的一款应用框架,出名,强大.所谓的框架其实就是一个集成了相应的功能且具有很强通用性的项目模板.(高性能的异步下载,解析,持久化……) 安装 linux mac os:pip ...

  5. 用描述符实现classmethod方法和staticmethod方法

    1. @classmethod class ClassMethod: def __init__(self, func): self.func = func def __get__(self, inst ...

  6. 二叉树的镜像(Python实现)

    题目 给定一棵二叉树,要求输出其左右翻转后二叉树的中序遍历. 例: 翻转前: 翻转后: 1 | 1 / \ | / \ 2 3 | 3 2 / \ | / \ 4 5 | 5 4 解析 两个步骤: 镜 ...

  7. 洛谷P2389 电脑班的裁员(区间DP)

    题目背景 隔壁的新初一电脑班刚考过一场试,又到了BlingBling的裁员时间,老师把这项工作交给了ZZY来进行.而ZZY最近忙着刷题,就把这重要的任务交(tui)给了你. 题目描述 ZZY有独特的裁 ...

  8. WebView的初体验

    使用安卓自带控件可以实现不通过浏览器即可上网的功能 突然就觉得安卓好强大,是不是我太无知了,太容易满足了 1.在layout中添加VebView控件 2.在Activity中设置WebView的属性 ...

  9. BZOJ 4971: [Lydsy1708月赛]记忆中的背包

    神仙构造 分成x个1和一堆>=w-x的大物品 (x<=20 w>=50) 则拼成w的方案中有且仅有一个大物品 若最终序列中有x个1,有一个大物品为w-k,可以提供C(x,k)种方案 ...

  10. Python协程详解(二)

    上一章,我们介绍了Python的协程,并讲到用yield达到协程的效果,这一章,我们来介绍yield from的结构和作用 我们先来对比下yield和yield from的用法 def first_g ...