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

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

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

思路:
每个开关最多只按一次,因为按了2次之后,就会抵消了。

可以从结果出发,也就是全灭状态怎么按能变成初始状态。

用3*3来举个例子,$X\left ( i,j \right )$表示这些开关是按还是不按,那么对于第一个开关,对它有影响的就只有2、4这两个开关,所以它的异或方程组就是:

$X\left ( 1,1 \right )*A\left ( 1,1 \right )  XOR  X\left ( 2,2 \right )*A\left ( 2,2 \right )...XOR  X\left ( 9,9 \right )*A\left ( 9,9 \right ) = $初始状态

这样一来就有30个异或方程组,高斯消元解一下即可。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn = 100 + 5;
17
18 int ans[maxn];
19 int c[maxn][maxn];
20
21 void Gauss()
22 {
23     int i=0,j=0,k,r;
24     for(k=0;k<30;k++)  //现在处理第k行
25     {
26         i=k;
27         while(c[i][k]==0 && i<30)  i++;  //找到一行第k列元素不为0
28         if(i!=k) for(j=0;j<=30;j++)  //交换两行
29             swap(c[k][j],c[i][j]);
30
31         //消元与回代合并了
32         for(i=0;i<30;i++)  if(k!=i && c[i][k])
33             for(j=k;j<=30;j++)  c[i][j]=c[k][j]^c[i][j];
34     }
35     for(int i=0;i<30;i++)
36         ans[i]=c[i][30];
37 }
38
39 int main()
40 {
41     //freopen("in.txt","r",stdin);
42     int T;
43     int kase=0;
44     scanf("%d",&T);
45     while(T--)
46     {
47         memset(c,0,sizeof(c));
48         for(int i=0;i<30;i++)  scanf("%d",&c[i][30]);
49
50         for (int i=0;i<30;i++)
51         {
52             c[i][i]=1;
53             if (i%6!=0) c[i-1][i]=1;
54             if (i%6!=5) c[i+1][i]=1;
55             if (i>5)    c[i-6][i]=1;
56             if (i<24)   c[i+6][i]=1;
57         }
58
59         Gauss();
60         printf ("PUZZLE #%d\n",++kase);
61         for (int i=0;i<30;i++)
62            printf (i%6==5?"%d\n":"%d ",ans[i]);
63     }
64     return 0;
65 }
时间: 2024-10-14 08:28:41

POJ 1222 EXTENDED LIGHTS OUT(高斯消元解XOR方程组)的相关文章

POJ 1222 extended lights out 高斯消元 板子题

题目链接:http://poj.org/problem?id=1222 题目描述:其实就是开关问题, 按下按钮会影响当前和周围的四个按钮, 问关闭所有灯的方案 解题思路:以前用搜索做过, 那时候是刚刚接触ACM的时候, 当时劲头真足啊, 这个解释的很好:http://blog.csdn.net/u013508213/article/details/47263183 代码: #include <iostream> #include <cstdio> #include <cstr

POJ 1222 EXTENDED LIGHTS OUT 高斯消元

点击打开链接 EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6492   Accepted: 4267 Description In an extended version of the game Lights Out, is a puzzle with 5 rows of 6 buttons each (the actual puzzle has 5 rows of 5 butt

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

[题目大意] 有n个数或为奇数或为偶数,现在进行m次操作,每次取出部分求和,告诉你这几次操作选取的数和它们和的奇偶性.如果通过这m次操作能得到所有数的奇偶性,则输出进行到第n次时即可求出答案:否则输出无法确定. [思路] 高斯消元解xor方程组,求最少需要的方程个数或判断无法确定. 无法确定即存在自由元,在每次操作中找1的时候判断一下就好了:最小方程个数,就是记录下每次找到的最小的1的位置,最后输出最大值即可. [错误] 忘记把ans改为-1了(见程序注释) [备注] P.S.我看别人在高斯消元

UVA 1560 - Extended Lights Out(高斯消元)

UVA 1560 - Extended Lights Out 题目链接 题意:给定一个矩阵,1代表开着灯,0代表关灯,没按一个开关,周围4个位置都会变化,问一个按的方法使得所有灯都变暗 思路:两种做法: 1.枚举递推 这个比较简单,就枚举第一行,然后递推过去,每次如果上一行是亮灯,则下一行开关必须按下去 2.高斯消元, 这个做法比较屌一些,每个位置对应上下左右中5个位置可以列出一个异或表达式,然后30个位置对应30个异或表达式,利用高斯消元法就能求出每个位置的解了 代码: 高斯消元法: #inc

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

题目链接:http://poj.org/problem?id=1830 题意:中文题诶- 思路:高斯消元解 mod2 方程组 有 n 个变元,根据给出的条件列 n 个方程组,初始状态和终止状态不同的位置对应的方程右边常数项为1,状态相同的位置对于的方程组右边的常数项为0.然后用高斯消元解一下即可.若有唯一解输出1即可,要是存在 k 个变元,则答案为 1 << k, 因为每个变元都有01两种选择嘛- 代码: 1 #include <iostream> 2 #include <s

【高斯消元解XOR方程】POJ1222-EXTENDED

[题目大意] 有5*6盏灯,每次开/关一个灯,上下左右的灯状态也会反转.问怎么使状态统一? [思路] 典型高斯消元解XOR方程,注意每盏灯要么0次要么1次. 1 #include <iostream> 2 #include <stdio.h> 3 #include <algorithm> 4 #include <set> 5 using namespace std; 6 int a[40][40]; 7 void gauss() 8 { 9 int i,j,

【POJ1222】EXTENDED LIGHTS OUT 高斯消元、解异或方程组

#include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/43481693"); } 题意: 多组数据. 有个5*6的图,然后你要对某些位置进行操作,使得最后灯的状态如图. 操作:这个灯位置的上下左右以及自己这五盏灯状态都取反. 然后输出操作. 说实话什么亮灭什么我全都没考虑. 直接瞎写一遍就PE了,

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

题目链接:http://poj.org/problem?id=1753 题意:一个 4*4 的棋盘,初始时上面放满了黑色或白色的棋子.对 (i, j) 位置进行一次操作后 (i, j), (i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1) 位置的棋子会变成原来相反的状态.问最少需要多少步可以将棋盘上的棋子全部变成白色或者黑色. 思路:分别将棋子变成黑色和白色,然后再用高斯消元解,其中步数较小者即为答案. 注意不存在唯一解时需要枚举自由变元来取得最小步数.

POJ 1222【异或高斯消元|二进制状态枚举】

题目链接:[http://poj.org/problem?id=1222] 题意:Light Out,给出一个5 * 6的0,1矩阵,0表示灯熄灭,反之为灯亮.输出一种方案,使得所有的等都被熄灭. 题解:首先可以用高斯消元来做,对于每个点,我们列出一个方程,左边是某个点和它相邻的点,他们的异或值等于右边的值(灯亮为1 ,灯灭为0),然后求一个异或高斯消元就可以了.可以用bitset优化,或者__int128优化(其实unsigned就可以了). 还可以枚举第一行的按开关的状态共有1<<6中状态