zoukankan      html  css  js  c++  java
  • POJ 1222 EXTENDED LIGHTS OUT(高斯消元)

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

    题意:就是给你一个初始矩阵(里面每个元素代表一个开关),改变一个开关就可以使得在其上、下、左、右的开关的状态都改变。问若使得所有开关均关闭(开关开为1,关为0),则需要改变哪些开关,并给出要改变的开关的矩阵图,里面的元素为1的表示要改变的开关,为0的表示不要变的开关。

    思路:一共30盏灯,每盏灯的方程为   x(i*6+j)+x((i-1)*6+j)+x((i+1)*6+j)+x(i*6+j-1)+x(i*6+j+1)=b(mod 2)。我们知道每盏灯最后状态有本身以及上下左右的5盏灯决定,5盏灯的异或值就是最终的状态,只要求解这个模2方程即可。

    code:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int MAXN = 40;
     8 //有equ个方程,var个变元。增广矩阵行数为equ,列数为var+1,分别为0到var
     9 int equ, var;
    10 int a[MAXN][MAXN]; //增广矩阵
    11 int x[MAXN]; //解集
    12 int free_x[MAXN];//用来存储自由变元(多解枚举自由变元可以使用)
    13 int free_num;//自由变元的个数
    14 
    15 //返回值为-1表示无解,为0是唯一解,否则返回自由变元个数
    16 int Gauss() {
    17     int max_r, col, k;
    18     free_num = 0;
    19     for (k = 0, col = 0; k <equ&& col <var; k++, col++) {
    20         max_r = k;
    21         for (int i = k + 1; i<equ; i++) {
    22             if (abs(a[i][col]) > abs(a[max_r][col]))
    23                 max_r = i;
    24         }
    25         if (a[max_r][col] == 0) {
    26             k--;
    27             free_x[free_num++] = col;//这个是自由变元
    28             continue;
    29         }
    30         if (max_r != k) {
    31             for (int j = col; j < var + 1; j++)
    32                 swap(a[k][j], a[max_r][j]);
    33         }
    34         for (int i = k + 1; i<equ; i++) {
    35             if (a[i][col] != 0) {
    36                 for (int j = col; j < var + 1; j++)
    37                     a[i][j] ^= a[k][j];
    38             }
    39         }
    40     }
    41     for (int i = k; i<equ; i++)
    42     if (a[i][col] != 0)
    43         return -1;//无解
    44     if (k <var) return var - k;//自由变元个数
    45     //唯一解,回代
    46     for (int i = var - 1; i >= 0; i--) {
    47         x[i] = a[i][var];
    48         for (int j = i + 1; j <var; j++)
    49             x[i] ^= (a[i][j] && x[j]);
    50     }
    51     return 0;
    52 }
    53 
    54 int t[MAXN][MAXN];
    55 int dir[5][2] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
    56 
    57 void init() {
    58     memset(t, 0, sizeof(t));
    59     for (int i = 0; i < 5; ++i) {
    60         for (int j = 0; j < 6; ++j) {
    61             for (int k = 0; k < 5; ++k) {
    62                 int a = i + dir[k][0];
    63                 int b = j + dir[k][1];
    64                 if (a >= 0 && b >= 0 && a < 5 && b < 6) {
    65                     t[6 * i + j][6 * a + b] = 1;
    66                 }
    67             }
    68         }
    69     }
    70 }
    71 
    72 int main()
    73 {
    74     init();
    75     int T;
    76     scanf("%d", &T);
    77     for (int cas = 1; cas <= T; ++cas) {
    78         memcpy(a, t, sizeof(a));
    79         for (int i = 0; i < 30; ++i) {
    80             scanf("%d", &a[i][30]);
    81         }
    82         printf("PUZZLE #%d
    ", cas);
    83         equ = 30;
    84         var = 30;
    85         if (Gauss() == 0) {
    86             for (int i = 0; i < 30; ++i) {
    87                 if (i % 6 == 5) {
    88                     printf("%d
    ", x[i]);
    89                 }
    90                 else {
    91                     printf("%d ", x[i]);
    92                 }
    93             }
    94         }
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    父页面与子页面间相互传值
    PS常用技能综合
    JS 提交form表单
    html实体字符
    js基础
    Delegate模式
    IOS-基础知识
    测试工具综合
    [Linux] Nginx 提供静态内容和优化积压队列
    [Linux] Nginx响应压缩gzip
  • 原文地址:https://www.cnblogs.com/ykzou/p/4862995.html
Copyright © 2011-2022 走看看