题目链接: http://poj.org/problem?id=1222

题意: 有一个 5 * 6 的初始矩阵, 1 表示一个亮灯泡, 0 表示一个不亮的灯泡. 对 (i, j) 位置进行一次操作则 (i, j), (i + 1, j), (i - 1, j), (i, j - 1),  (i, j + 1) 位置的灯泡变为原来的相反状态, 输出一种能让所有灯泡都变成不亮状态的操作集合.

思路:

1. 可以先枚举第一行的所有操作集合, 2^6 种, 第一行的每一种操作后都得到一个灯泡状态集合, 然后再根据第一行的灯泡状态确定第二行的操作, 若 (1, j) 亮, 则(2, j) 必定要进行一次操作, 若(1, j) 不亮, 则 (2, j) 一定不能进行操作. 依次根据上一行的灯泡状态确定下一行的操作. 然后再对最后一行灯泡的状态进行检查, 若全部不亮则得到一个解.

代码:

 #include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std; const int N = ;
const int M = ;
const int MAXN = ;
int mp[MAXN][MAXN], sol[MAXN][MAXN];
bool flag = false;
int cas; bool check(void){
int gel[MAXN][MAXN];
memcpy(gel, mp, sizeof(mp));
for(int i = ; i <= M; i++){
if(sol[][i]){
gel[][i] ^= ;
gel[][i - ] ^= ;
gel[][i + ] ^= ;
gel[][i] ^= ;
gel[][i] ^= ;
}
}
for(int i = ; i <= N; i++){
for(int j = ; j <= M; j++){
if(gel[i - ][j]){
sol[i][j] = ;
gel[i][j] ^= ;
gel[i][j - ] ^= ;
gel[i][j + ] ^= ;
gel[i - ][j] ^= ;
gel[i + ][j] ^= ;
}else sol[i][j] = ;
}
}
for(int i = ; i <= M; i++){
if(gel[N][i]) return false;
}
printf("PUZZLE #%d\n", cas);
for(int i = ; i <= N; i++){
for(int j = ; j <= M; j++){
cout << sol[i][j] << " ";
}
cout << endl;
}
return true;
} void dfs(int m){
if(flag) return;
if(m > M){
if(check()) flag = true;
return;
}
sol[][m] = ;
dfs(m + );
sol[][m] = ;
dfs(m + );
} int main(void){
int t;
cin >> t;
for(cas = ; cas <= t; cas++){
for(int i = ; i <= N; i++){
for(int j = ; j <= M; j++){
cin >> mp[i][j];
}
}
flag = false;
dfs();
if(!flag){
printf("PUZZLE #%d\n", cas);
cout << "inf" << endl;
}
}
return ;
}

2. 把 30 个灯泡对应的操作当作 30 个未知数, 其解为 1 或 0, 1 表示对该位置进行一次操作, 0 表示不对该位置进行操作, 每个操作对应一个 1* 30 系数矩阵, 1 表示进行该操作后这个位置的灯泡状态会改变, 0 表示进行该操作后该位置的灯泡状态不会改变. 然后可以列 30 个方程, 常数项为对应位置的灯泡初始状态. 然后直接用高斯消元解一下即可.

关于高斯消元:

高斯消元法的原理是:
若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程组。
所以我们可以用初等行变换把增广矩阵转换为行阶梯阵,然后回代求出方程的解。
以上是线性代数课的回顾,下面来说说高斯消元法在编程中的应用。
首先,先介绍程序中高斯消元法的步骤:
(我们设方程组中方程的个数为equ,变元的个数为var,注意:一般情况下是n个方程,n个变元,但是有些题目就故意让方程数与变元数不同)
1. 把方程组转换成增广矩阵。
2. 利用初等行变换来把增广矩阵转换成行阶梯阵。
枚举k从0到equ – 1,当前处理的列为col(初始为0) ,每次找第k行以下(包括第k行),col列中元素绝对值最大的列与第k行交换。如果col列中的元素全为0,那么则处理col + 1列,k不变。
3. 转换为行阶梯阵,判断解的情况。
① 无解
当方程中出现(0, 0, …, 0, a)的形式,且a != 0时,说明是无解的。
② 唯一解
条件是k = equ,即行阶梯阵形成了严格的上三角阵。从最后一行开始回代逐一求出解集。
③ 无穷解。
条件是k < equ,即不能形成严格的上三角形,自由变元的个数即为equ – k,但有些题目要求判断哪些变元是不缺定的。
    这里单独介绍下这种解法:
首先,自由变元有var - k个,即不确定的变元至少有var - k个。我们先把所有的变元视为不确定的。在每个方程中判断不确定变元的个数,如果大于1个,则该方程无法求解。如果只有1个变元,那么该变元即可求出,即为确定变元。

这段话是从其他博客中摘过来的.

代码:

 #include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std; const int MAXN = 3e2;
int equ = , var = ;//有equ个方程,var个变元,增广矩正行数为equ,列数为var+1,从0开始计数
int a[MAXN][MAXN];//增广矩正
int free_x[MAXN];//用来存储自由变元(多解枚举自由变元可以使用)
int free_num;//自由变元个数
int x[MAXN];//解集 int Gauss(void){//返回-1表示无解,0表示有唯一解,否则返回自由变元个数
int max_r, col, k;
free_num = ;
for(k = , col = ; k < equ && col < var; k++, col++){
max_r = k;
for(int i = k + ; i < equ; i++){
if(abs(a[i][col] > abs(a[max_r][col]))) max_r = i;
}
if(a[max_r][col] == ){
k--;
free_x[free_num++] = col;//这个是变元
continue;
}
if(max_r != k){
for(int j = col; j < var + ; j++){
swap(a[k][j], a[max_r][j]);
}
}
for(int i = k + ; i < equ; i++){
if(a[i][col] != ){
for(int j = col; j < var + ; j++){
a[i][j] ^= a[k][j];
}
}
}
}
for(int i = k; i < equ; i++){
if(a[i][col] != ) return -;//无解
}
if(k < var) return var - k;//返回自由变元个数
for(int i = var - ; i >= ; i--){
x[i] = a[i][var];
for(int j = i + ; j < var; j++){
x[i] ^= (a[i][j] && x[j]);
}
}
return ;
} int main(void){
int t, n;
cin >> t;
for(int cas = ; cas <= t; cas++){
for(int i = ; i < ; i++){
cin >> a[i][];
x[i] = ;//清空数组
}
for(int i = ; i < ; i++){//构造增广矩阵
int x1 = i / ;
int y1 = i % ;
for(int j = ; j < ; j++){
int x2 = j / ;
int y2 = j % ;
if(abs(x1 - x2) + abs(y1 - y2) < ) a[j][i] = ;
else a[j][i] = ;
}
}
Gauss();
cout << "PUZZLE #" << cas << endl;
for(int i = ; i < ; i++){
cout << x[i] << " ";
if((i + ) % == ) cout << endl;
}
}
return ;
}

poj1222(枚举or高斯消元解mod2方程组)的更多相关文章

  1. poj1681(枚举or高斯消元解mod2方程组)

    题目链接: http://poj.org/problem?id=1681 题意: 有一个包含 n * n 个方格的正方形, w 表示其所在位置为白色, y 表示其所在位置为黄色. 对 (i, j) 位 ...

  2. poj1830(高斯消元解mod2方程组)

    题目链接:http://poj.org/problem?id=1830 题意:中文题诶- 思路:高斯消元解 mod2 方程组 有 n 个变元,根据给出的条件列 n 个方程组,初始状态和终止状态不同的位 ...

  3. poj1753(高斯消元解mod2方程组)

    题目链接:http://poj.org/problem?id=1753 题意:一个 4*4 的棋盘,初始时上面放满了黑色或白色的棋子.对 (i, j) 位置进行一次操作后 (i, j), (i + 1 ...

  4. 【高斯消元解xor方程组】BZOJ2466-[中山市选2009]树

    [题目大意] 给出一棵树,初始状态均为0,每反转一个节点的状态,相邻的节点(父亲或儿子)也会反转,问要使状态均为1,至少操作几次? [思路] 一场大暴雨即将来临,白昼恍如黑夜!happy! 和POJ1 ...

  5. POJ 1222 EXTENDED LIGHTS OUT(高斯消元解XOR方程组)

    http://poj.org/problem?id=1222 题意:现在有5*6的开关,1表示亮,0表示灭,按下一个开关后,它上下左右的灯泡会改变亮灭状态,要怎么按使得灯泡全部处于灭状态,输出方案,1 ...

  6. 【高斯消元解xor方程】BZOJ1923-[Sdoi2010]外星千足虫

    [题目大意] 有n个数或为奇数或为偶数,现在进行m次操作,每次取出部分求和,告诉你这几次操作选取的数和它们和的奇偶性.如果通过这m次操作能得到所有数的奇偶性,则输出进行到第n次时即可求出答案:否则输出 ...

  7. bzoj千题计划187:bzoj1770: [Usaco2009 Nov]lights 燈 (高斯消元解异或方程组+枚举自由元)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1770 a[i][j] 表示i对j有影响 高斯消元解异或方程组 然后dfs枚举自由元确定最优解 #in ...

  8. [置顶] hdu 4418 高斯消元解方程求期望

    题意:  一个人在一条线段来回走(遇到线段端点就转变方向),现在他从起点出发,并有一个初始方向, 每次都可以走1, 2, 3 ..... m步,都有对应着一个概率.问你他走到终点的概率 思路: 方向问 ...

  9. 【BZOJ】2466: [中山市选2009]树 高斯消元解异或方程组

    [题意]给定一棵树的灯,按一次x改变与x距离<=1的点的状态,求全0到全1的最少次数.n<=100. [算法]高斯消元解异或方程组 [题解]设f[i]=0/1表示是否按第i个点的按钮,根据 ...

随机推荐

  1. java代码分解质因数

    总结: 循环...首位 逻辑要清晰 很简单.首先质因数最小的2.因为1不是质数 然后当输入的数刚好为2时,结束.不用下一步了.否则在循环里不停的输出一个数, 当输入的数比2大时,分能被2整除和不能被2 ...

  2. top命令 Linux查看CPU和内存使用情况,cpu监控之一

    一.top命令 top命令是一个功能十分强大的监控系统的工具,对于系统管理员而言尤其重要.但是,它的缺点是会消耗很多系统资源. 在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分 ...

  3. mybatis 学习五 动态SQL语句

    3.1 selectKey 标签 在insert语句中,在Oracle经常使用序列.在MySQL中使用函数来自动生成插入表的主键,而且需要方法能返回这个生成主键.使用myBatis的selectKey ...

  4. [置顶] if语句的陷阱

    if else if是只要有满足条件的,就不再对之后的else if进行判断 #include<stdio.h> void main() { char a=0; if(a==0) { a= ...

  5. 数据库:sql 多表联合更新【转】

    SQL Update多表联合更新的方法 (1) sqlite 多表更新方法 update t1 set col1=t2.col1 from table1 t1 inner join table2 t2 ...

  6. appium_python-测试报告模板话化

    我们用python拓展模板 HTMLTestRunner.py python3 要自己重新改写下输出输入接口,可直接下载 改好的 地址 链接:http://pan.baidu.com/s/1hsOBw ...

  7. maven依赖的添加

      maven可是个管理jar依赖的好玩意,不用再关心导这个jar包那个jar包,这个jar包是谁家的,和谁有啥关系.有了maven,简简单单就搞定,下面以eclipse为例,在一个springboo ...

  8. Javascript面向对象(三):非构造函数的继承

    这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使用构造函数实现"继承". 一.什么是 ...

  9. chosen.jquery插件的使用

    前几天在jQuery官网看到了插件里面有400多个插件,看了下效果都很好,以后项目里面难免会用到.于是下了个决定,有时间把官网的插件都研究下,并简单介绍他的用法,方便以后的使用. 下面将要提到的是jQ ...

  10. [P3812][模板]线性基

    解题关键:求异或最大值.线性基模板题. 极大线性无关组的概念. 异或的值域相同. #include<cstdio> #include<cstring> #include< ...