POJ 1222 (开关问题+高斯消元法)

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

题目大意:一堆开关,或开或关。每个开关按下后,周围4个方向开关反转。问使最后所有开关都关闭的,开关按法。0表示不按,1表示按。

解题思路

一共只有5*6个开关。

对于每个开关,设其最终状态为x5,上下左右四个开关最终状态分别为x1,x2,x3,x4,

那么有方程x1^x2^x3^x4^x5^初始状态=0。

这样就有30个方程。解这30个线性方程组即可。

用高斯消元法来解方程组,变化如下:

①对于原本找列中绝对值最大这一步,可以简化成找第一个为1的k,因为系数矩阵不是0就是1,最大就是1。

②原本的+号现在变成^号。

这里推荐一下cxlove神牛的简洁写法,他把col和row合二而一,又将解向量和系数矩阵合二为一,非常吊。

#include "cstdio"
#include "iostream"
using namespace std;
int ratio[31][31],dir[5][2]={0,0,-1,0,1,0,0,-1,0,1};
void reset()
{
    for(int i=0; i<5; i++)
        for(int j=0; j<6; j++)
            for(int k=0; k<5; k++)
            {
                int x=i+dir[k][0],y=j+dir[k][1];
                if (x>=0&&y>=0&&x<5&&y<6) ratio[i*6+j][x*6+y]=1;
            }
}
void guess()
{
    for(int i=0;i<30;i++)
    {
        int k=i;
        for(;k<30;k++)
            if(ratio[k][i]!=0) break;
        for(int j=0;j<=30;j++) swap(ratio[i][j],ratio[k][j]);
        for(int j=0;j<30;j++)
        {
            if(i!=j&&ratio[j][i])
                for(int k=0;k<=30;k++)
                   ratio[j][k]=ratio[i][k]^ratio[j][k];
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int T,no=0;
    scanf("%d",&T);
    while(T--)
    {
        printf("PUZZLE #%d\n",++no);
        reset();
        for(int i=0;i<30;i++) scanf("%d",&ratio[i][30]);
        guess();
        for(int i=0;i<30;i++)
        {
            printf("%d",ratio[i][30]);
            if(i%6==5) printf("\n");
            else printf(" ");
        }

    }
}
13596495 neopenx 1222 Accepted 160K 0MS C++ 1186B 2014-11-04 00:51:23
时间: 2024-08-04 13:41:46

POJ 1222 (开关问题+高斯消元法)的相关文章

POJ 1681 (开关问题+高斯消元法)

题目链接: http://poj.org/problem?id=1681 题目大意:一堆格子,或白或黄.每次可以把一个改变一个格子颜色,其上下左右四个格子颜色也改变.问最后使格子全部变黄,最少需要改变几个格子. 解题思路: 与POJ 1222类似. 一共只有15*15个格子,设初始解向量黄为0,白为1. 对于每个开关,设其改变状态为x5,上下左右四个开关改变状态分别为x1,x2,x3,x4, 那么有方程x1^x2^x3^x4^x5^初始状态=0. 这样就有15*15个方程.解这15*15个线性方

poj 1830 开关问题 高斯消元法

开关问题 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5854   Accepted: 2213 Description 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开.你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态.对于任意一个开关,最多只能进行一次开关操作

poj 一类开关问题

这是一类开关问题,对于这类问题可以状态压缩枚举搞,也可以用高斯消元,当数据量比较大的时候高斯消元效率更高. poj 1222 状态压缩枚举第一行所有的翻转情况,从第二行开始依次递推即可. #include <iostream> #include <stdio.h> #include <string> #include <string.h> #include <algorithm> using namespace std; int dx[5]={0

POJ 1830 开关问题

简单的高斯消元取模,答案为2^自由变元的数量,但是题目的意思把I,J搞反了,坑爹... 开关问题 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5425   Accepted: 2023 Description 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开.你的目标是经过若干次

poj 1830 开关问题 高斯消元

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

POJ - 1222: EXTENDED LIGHTS OUT (开关问题-高斯消元)

pro:给定5*6的灯的状态,如果我们按下一个灯的开关,它和周围4个都会改变状态.求一种合法状态,使得终状态全为关闭: sol:模2意义下的高斯消元. 终于自己手打了一个初级板子. #include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; int a[40][40],ans[40]; int x[5]={0,0,0,1,-1}; int y[5]={0,1,-1,0,0};

poj 1222 EXTENDED LIGHTS OUT 高斯消元法

EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6872   Accepted: 4532 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 buttons eac

POJ 1222 高斯消元法解开关问题

#include <cstdio> #include <cstring> #include <algorithm> const int maxn = 30; int inp[maxn + 5][maxn + 5], kase, T; void gauss() { for (int i = 0; i < maxn; i++) { int k = i; while (k < maxn && !inp[k][i])k++; for (int j =

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