uva 1560 - Extended Lights Out(枚举 | 高斯消元)

题目链接:uva 1560 - Extended Lights Out

题目大意:给定一个5?6的矩阵,每个位置上有一个灯和开关,初始矩阵表示灯的亮暗情况,如果按了这个位置的开关,将会导致周围包括自己位置的灯状态变换,求一个按开关位置,保证所有灯都灭掉。

解题思路:

  1. 枚举,枚举第一行的状态,然后递推出后面四行的状态。
  2. 高斯消元,对于每个位置对定变量,这样列出30个方程求解。
C++ 枚举

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 10;
const int R = 5;
const int C = 6;

int arr[maxn][maxn], v[maxn][maxn], p[maxn][maxn];

bool judge (int s) {
    memset(p, 0, sizeof(p));
    memset(v, 0, sizeof(v));

    for (int i = 0; i < C; i++) {
        if (s&(1<<i)) {
            p[1][i+1] = 1;

            for (int j = 0; j <= 2; j++)
                v[1][i+j] ^= 1;
            v[2][i+1] ^= 1;
        }
    }

    for (int i = 2; i <= R; i++) {
        for (int j = 1; j <= C; j++)
            if (v[i-1][j]^arr[i-1][j]) {
                p[i][j] = 1;

                for (int k = -1; k <= 1; k++)
                    v[i][j+k] ^= 1;
                v[i+1][j] ^= 1;
            }
    }

    for (int i = 1; i <= C; i++)
        if (v[R][i]^arr[R][i])
            return false;

    for (int i = 1; i <= R; i++) {
        for (int j = 1; j < C; j++)
            printf("%d ", p[i][j]);
        printf("%d\n", p[i][C]);
    }
    return true;
}

int main () {
    int cas;
    scanf("%d", &cas);
    for (int kcas = 1; kcas <= cas; kcas++) {

        for (int i = 1; i <= R; i++)
            for (int j = 1; j <= C; j++)
                scanf("%d", &arr[i][j]);

        printf("PUZZLE #%d\n", kcas);
        for (int s = 0; s < (1<<C); s++)
            if (judge(s))
                break;
    }
    return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int dir[5][2] = {{0, 0}, {1, 0}, {-1, 0}, {0, 1}, {0, -1}};
const int maxn = 30;
const int R = 5;
const int C = 6;
typedef int Mat[maxn+5][maxn+5];

Mat A;
int v[R+5][C+5];

void init () {
    memset(A, 0, sizeof(A));
    memset(v, 0, sizeof(v));
    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            int x = i * C + j;
            scanf("%d", &A[x][maxn]);
            for (int k = 0; k < 5; k++) {
                int p = i + dir[k][0];
                int q = j + dir[k][1];
                if (p < 0 || p >= R || q < 0 || q >= C)
                    continue;
                A[x][p*C+q] = 1;
            }
        }
    }
}

void gauss_elimination (Mat a, int n) {

    for (int i = 0; i < n; i++) {

        int r = i;
        while (A[r][i] == 0)
            r++;

        if (r != i) {
            for (int j = 0; j <= n; j++)
                swap(A[i][j], A[r][j]);
        }

        for (int j = i + 1; j < n; j++) {
            if (A[j][i]) {
                for (int k = 0; k <= n; k++)
                    A[j][k] ^= A[i][k];
            }
        }
    }

    for (int i = n - 1; i >= 0; i--) {
        for (int j = i + 1; j < n; j++)
            A[i][n] ^= (A[j][n] * A[i][j]);
        if (A[i][n])
            v[i/C][i%C] = 1;
    }
}

int main () {
    int cas;
    scanf("%d", &cas);
    for (int kcas = 1; kcas <= cas; kcas++) {
        init();
        gauss_elimination(A, maxn);
        printf("PUZZLE #%d\n", kcas);
        for (int i = 0; i < R; i++) {
            printf("%d", v[i][0]);
            for (int j = 1; j < C; j++)
                printf(" %d", v[i][j]);
            printf("\n");
        }
    }
    return 0;
}

uva 1560 - Extended Lights Out(枚举 | 高斯消元),布布扣,bubuko.com

时间: 2024-12-25 02:46:13

uva 1560 - Extended Lights Out(枚举 | 高斯消元)的相关文章

「ZOJ 1354」Extended Lights Out「高斯消元」

题意:给定一个\(5\times 6\)的棋盘的\(01\)状态,每次操作可以使它自己和周围四个格子状态取反,求如何操作,输出一个\(01\)矩阵 题解:这题可以通过枚举第一行的状态然后剩下递推来做,但是这里还是写一种好理解的高斯消元解异或方程组的方法. 对于每个格子列一个方程,未知数就是要求的答案矩阵,系数的话把它周围的设为1,其他设为0.然后右边的常数项为它本来的状态.然后就高斯消元嘛. 我用了bitset优化,实际上可能unsigned int或者long long也可以. #includ

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这两个开关,所以它的异或方程

POJ 1222 EXTENDED LIGHTS OUT(高斯消元)

[题目链接] http://poj.org/problem?id=1222 [题目大意] 给出一个6*5的矩阵,由0和1构成,要求将其全部变成0,每个格子和周围的四个格子联动,就是说,如果一个格子变了数字,周围四格都会发生变化,变化即做一次与1的异或运算,输出每个格子的操作次数. [题解] 高斯消元练手题,对于每个格子的最终情况列一个方程,一共三十个方程三十个未知数,用高斯消元求解即可. [代码] #include <cstdio> #include <algorithm> #in

【POJ】1222 EXTENDED LIGHTS OUT(高斯消元)

http://poj.org/problem?id=1222 竟然我理解了两天..... 首先先来了解异或方程组(或者说mod2方程组,modk的话貌似可以这样拓展出来) 对于一些我们需要求出的变量a[1~n],我们现在知道n个方程组(有解的情况下),每个方程均是类似原版消元那样带了个系数的,只不过这个系数只有0和1,那么我们第i个方程用x[i, 1~n]表示a[1~n]的系数,然后x[n+1]为这个方程的右式 那么这些方程组是这样的 (x[1,1]*a[1])^(x[1,2]*a[2])^..

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

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

uva 10808 - Rational Resistors(基尔霍夫定律+高斯消元)

题目链接:uva 10808 - Rational Resistors 题目大意:给出一个博阿含n个节点,m条导线的电阻网络,求节点a和b之间的等效电阻. 解题思路:基尔霍夫定律,任何一点的电流向量为0.就是说有多少电流流入该节点,就有多少电流流出. 对于每次询问的两点间等效电阻,先判断说两点是否联通,不连通的话绝逼是1/0(无穷大).联通的话,将同一个联通分量上的节点都扣出来,假设电势作为变元,然后根据基尔霍夫定律列出方程,因为对于每个节点的电流向量为0,所以每个节点都有一个方程,所有与该节点

UVA 10828 - Back to Kernighan-Ritchie(概率+高斯消元)

UVA 10828 - Back to Kernighan-Ritchie 题目链接 题意:给图一个流程图,有结点的流程,每次进入下一个流程概率是均等的,有q次询问,求出每次询问结点的执行期望 思路:高斯消元,每个结点的期望等于所有前趋结点的期望/出度的和,由于存在无限循环的情况,不能直接递推,利用高斯消元去做,判断无解的情况既为无限循环,注意如果一个式自xi为0,但是xn也为0,xi值应该是0,表示无法到达 代码: #include <cstdio> #include <cstring

BZOJ 1770 [Usaco2009 Nov]lights 燈 【高斯消元】

Description 貝希和她的閨密們在她們的牛棚中玩遊戲.但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了.貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望.她希望您能夠幫幫她,把所有的燈都給重新開起來!她才能繼續快樂地跟她的閨密們繼續玩遊戲! 牛棚中一共有N(1 <= N <= 35)盞燈,編號為1到N.這些燈被置於一個非常複雜的網絡之中.有M(1 <= M <= 595)條很神奇的無向邊,每條邊連接兩盞燈. 每盞燈上面都帶有一個開關.當

小结:高斯消元

对于一组多项式方程(增广矩阵中,x[i, n+1]表示式子的值:x[i,j]表示第i个方程第j项的系数,在这里,增广矩阵可能不一定是n个,可能多可能少:opt表示运算规则): (x[1,1]*a[1]) opt (x[1,2]*a[2]) opt ... opt (x[1,n]*a[n])=x[1, n+1] (x[2,1]*a[1]) opt (x[2,2]*a[2]) opt ... opt (x[2,n]*a[n])=x[2, n+1] ... (x[n,1]*a[1]) opt (x[n