参考博客 https://blog.csdn.net/so_so_y/article/details/76098713

题意

有一些灯泡组成了5*6的方阵。每个开关(开关会使灯泡的状态发生变化)除了控制它本身的灯泡以外,还同时控制上下左右四个方向的灯泡(如果有的话)。给出灯泡的初始状态,如果想吧所有的灯泡都关闭,应该按下哪些开关。0代表灯泡关闭,1代表灯泡打开。

分析

高斯消元解决开关问题的模板题。

这一类开关问题可以先转化为异或方程组,然后通过高斯消元解线性方程的方法进行求解。我们先来看一下该怎么转化。

它给出了初始的状态,我们把它看作一个n*m 01的矩阵L,开灯为1,关灯为0。那么目标状态也很明确,是一个n*m的全为0的矩阵。

每个开关控制的灯泡最多有五个(上下左右和它本身),我们把每个开关控制的灯泡都转换成矩阵,控制到的为1,没有控制到的为0。比如说如果灯泡组成的方阵使2*3的,那么一共有6个开关,每个开关所控制的矩阵(A1-A6)为

开关1:   1 1 0      开关5: 0 1 0   开关6:0 0 1

1 0 0                    1 1 1                0 1 1

每个开关只有两种状态,我们用1代表按下开关,0代表不安。开关的状态显然也是一个n*m的01矩阵,只不过是未知的(也是我们要求的)。

现在我们把上面这些状态通过异或组成方程

L xor A1*X xor A2*X xor A3 *X.....A6*X =0  注意:这里不是矩阵乘法,是点乘。

然后两遍同时异或L可以变成

A1*X xor A2*X xor A3*X ...A6*X=L

然后可以拆成

A1(1,1)*X(1,1) xor A2(1,1)*X(1, 2)....A6(1,1)*X(2,3)=L(1,1)

A1(5,6)*X(1,1) xor A2(5,6)*X(1,2)....A^(5,6)*X(2,3)=L(5,6)

现在我们就已经把题目转化为了一个线性的异或方程组。接下来通过高斯消元求解。

高斯消元求解异或方程组和求解普通方程组基本一样,就两个地方有一些区别。一个是消元的时候,普通方程组是将每个系数减去关键方程的系数和当前方程的比值和值的乘积(绕口令?),而异或方程组直接将每个系数和关键方程异或就好。另一个是回带求ans的时候,好吧说不太清楚,具体可以看代码。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath> using namespace std;
const int maxn=;
const int dx[]={,,,,-};
const int dy[]={,,-,,};
int a[maxn][maxn],ans[maxn];
int T,n,m;
void Gauss(){
int k,col;
for(k=,col=;k<n*m&&col<=n*m;k++,col++){
int i=k;
for(int j=k+;j<=n*m;j++){
if(fabs(a[j][col])>fabs(a[i][col]))i=j;
}
if(i!=k){
for(int j=;j<=n*m+;j++){
swap(a[k][j],a[i][j]);
}
}
if(a[k][col]==){
--col;
continue;
}
for(i=k+;i<=n*m;i++){
if(a[i][col]){
for(int j=;j<=n*m+;j++){
a[i][j]^=a[k][j];//是这样子吧?
}
}
}
}
for(int i=n*m;i>=;i--){
ans[i]=a[i][n*m+];
for(int j=i+;j<=n*m;j++){
ans[i]^=(ans[j]&&a[i][j]);
}
}
return;
}
int main(){
n=,m=;
scanf("%d",&T);
for(int t=;t<=T;t++){
memset(a,,sizeof(a));
memset(ans,,sizeof(ans));
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
int cnt=(i-)*m+j;
scanf("%d",&a[cnt][n*m+]);
}
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
for(int k=;k<;k++){
int nx=i+dx[k];
int ny=j+dy[k];
if(nx>=&&nx<=n&&ny>=&&ny<=m){
int cnt=(i-)*m+j;
a[(nx-)*m+ny][cnt]=;
}
}
}
}
Gauss();
printf("PUZZLE #%d\n",t);
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
int cnt=(i-)*m+j;
printf("%d ",ans[cnt]);
}
printf("\n");
}
}
return ;
}

【POJ1222】EXTENDED LIGHTS OUT的更多相关文章

  1. 【POJ 1222】 EXTENDED LIGHTS OUT

    [题目链接] http://poj.org/problem?id=1222 [算法] 列出异或方程组,用高斯消元求解即可 [代码] #include <algorithm> #includ ...

  2. 【POJ】1222 EXTENDED LIGHTS OUT

    [算法]高斯消元 [题解] 高斯消元经典题型:异或方程组 poj 1222 高斯消元详解 异或相当于相加后mod2 异或方程组就是把加减消元全部改为异或. 异或性质:00 11为假,01 10为真.与 ...

  3. 【12c】扩展数据类型(Extended Data Types)-- MAX_STRING_SIZE

    [12c]扩展数据类型(Extended Data Types)-- MAX_STRING_SIZE 在12c中,与早期版本相比,诸如VARCHAR2, NAVARCHAR2以及 RAW这些数据类型的 ...

  4. 【Silverlight】Bing Maps学习系列(六):使用扩展模式(Extended Modes)(转)

    [Silverlight]Bing Maps学习系列(六):使用扩展模式(Extended Modes) 微软Bing Maps推出有有段时间了,通过不断的改进和新的地图更新,现在已经基本上形成了一套 ...

  5. EXTENDED LIGHTS OUT poj1222 高斯消元法

    EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6443   Accepted: 42 ...

  6. 【BZOJ】1770 [Usaco2009 Nov]lights 燈

    [算法]高斯消元-异或方程组 [题解]良心简中题意 首先开关顺序没有意义. 然后就是每个点选或不选使得最后得到全部灯开启. 也就是我们需要一种确定的方案,这种方案使每盏灯都是开启的. 异或中1可以完美 ...

  7. 【codeforces 29B】Traffic Lights

    [题目链接]:http://codeforces.com/problemset/problem/29/B [题意] 一辆车; 让从A开到B; 然后速度是v; (只有在信号灯前面才能停下来..否则其他时 ...

  8. 【四】搭建Markdown的编辑器

    本系列有五篇:分别是 [一]Ubuntu14.04+Jekyll+Github Pages搭建静态博客:主要是安装方面 [二]jekyll 的使用 :主要是jekyll的配置 [三]Markdown+ ...

  9. 【原创】开源Math.NET基础数学类库使用(09)相关数论函数使用

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

随机推荐

  1. 虚拟路由冗余协议VRRP

    一.VRRP简介 虚拟路由冗余协议VRRP(Virtual Router Redundancy Protocol)通过把几台路由设备联合组成一台虚拟的路由设备,将虚拟路由设备的IP地址作为用户的默认网 ...

  2. Spring整合JavaMail

    1.添加jar包 #此处省略spring基础相关jar包描述,以下是发送邮件相关jar包 <dependency> <groupId>org.springframework&l ...

  3. javascript 中的 arguments,callee.caller,apply,call 区别

    记录一下: 1.arguments是一个对象, 是函数的一个特性,只有在函数内才具有这个特性,在函数外部不用使用. 举例: function test(){   alert(typeof argume ...

  4. NumPy-快速处理数据--矩阵运算

    本文摘自<用Python做科学计算>,版权归原作者所有. 1. NumPy-快速处理数据--ndarray对象--数组的创建和存取 2. NumPy-快速处理数据--ndarray对象-- ...

  5. bootstrap常用模态框

    <!-- 触发器(button) --> <button class="btn btn-xs btn-success" data-toggle="mod ...

  6. RandomStringUtils工具类(java随机生成字符串)

    使用RandomStringUtils可以选择生成随机字符串,可以是全字母,全数字,自定义生成字符等等... 其最基础的方法: 参数解读: count:需要生成的随机串位数 letters:只要字母 ...

  7. postman批量执行 要给请求加断言,批量执行的时候才会去统计,成功和失败的条数

    1.设置请求断言后保存 2.点击runner去批量执行 3.有断言的请求就会统计

  8. postman 请求 页面出现 Could not get any response 解决方法

    1.关闭掉证书 2.再关闭掉代理 3.去掉请求头的Content-Length字段 (或者一个个试请求头的值,看去掉那些就请求成功了) 后记: 网友 @ 重庆张晓祥 提供了个线索确实让我想起以前我从浏 ...

  9. node的socket.io的之事件篇

    socket.io类库不但可以相互发送消息,而且还可以通过socket端口对象的emit方法互相发送事件. emit在之前的事件上说过现在一句话带过:emit是用来手动触发事件的. socket.em ...

  10. 通过TortoiseGit来使用Github或Visual Studio Online版本控制管理

    一.前言 关于Git源码不再多阐述,它就是一款开源分布式版本控制工具,它在源码管理领土上目前为止,使用者比例很大,越来越多的人使用该工具来管理项目源码,且相当多的开源的项目都移步到Github中,如: ...