• poj1222 EXTENDED LIGHTS OUT


    设输入矩阵为A,输出矩阵为B,目标矩阵为C(零矩阵)。

    方便起见,矩阵行列下标均从1开始。

    考虑A矩阵元素a(i,j),B矩阵中与其相邻的元素 b(i,j),b(i - 1, j),b(i + 1,j),b(i,j - 1),b(i,j + 1) (#)。

    有c(i,j)= 0 = a(i,j) ^ (∑ b(i,j) % 2)。

    进一步有a(i,j) ^ 0 = a(i,j) = a(i,j) ^ a(i,j) ^ (∑ b(i,j) % 2) = ∑ b(i,j) % 2     (*)。

    进一步考虑异或与模2加之间的关系:∑ b(i,j) % 2 = ^ B(i, j),其中B(i,j)表示(#)式5个元素的集合。

    带入(*):^ B(i, j) = a(i,j)。这是我们需要的方程组。

    (注:考虑边界上的元素,只需将不在矩阵范围内的b元素全部置零即可。)

    将b(i,j)映射到x((i - 1) * 5 + j)(x下标从1到5 * 6)。

    下面考虑解异或方程组AX= B。(与前面的表达无关)

    a11 * x1 ^ a12 * x2 ^...^ a1n * xn = b1 ①

    ...

    an1 * x1 ^ an2 * x2 ^...^ann * xn = bn ②

    A,X,B均为0-1矩阵。

    考虑消元,现在看系数矩阵A的第一列,若全部元素均为0,直接转到下一列,并且有方程组有多解。

    若存在ai1 = 1,将其与第一行交换(这样做的目的是为了得到上三角阵)。

    此时只需考虑剩余所有 1 < j ≤ n, 且aj1 = 1。有:

    a11 * x1 ^ a12 * x2 ^...^ a1n * xn = b1 ①

    aj1 * x1 ^ aj2 * x2 ^...^ ajn * xn = bj ②

    ① ^ ②:

    (a11 * x1 ^ a12 * x2 ^...^ a1n * xn) ^ (aj1 * x1 ^ aj2 * x2 ^...^ ajn * xn) = b1 ^ bj。

    即:(a11 * x1 ^ aj1 * x1) ^ (a12 * x2 ^ aj2 * x2) ^...^ (a1n * xn ^ ajn * xn) = b1 ^ bj 。

    易于验证:a * x ^ b ^ x = (a ^ b) * x,因此进一步有:

    (a11 ^ aj1)*x1 ^ (a12 ^ aj2)*x2  ^ .... ^ (a1n ^ ajn)*xn = b1 ^ bj 。

    因而第j行x1的系数更新为1 ^ 1 即0 。 

    对增广阵如此消元至得到上三角阵即可得到答案。

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

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 const int maxx = 5;
     6 const int maxy = 6;
     7 const int maxm = maxx * maxy;
     8 const int maxn = maxm + 10;
     9 int A[maxn][maxn], B[maxn];
    10 int C[maxn][maxn];
    11 int dx[] = {0, 0, 0, -1, 1};
    12 int dy[] = {0, -1, 1, 0, 0};
    13 int pos(int i, int j) { return (i - 1) * maxy + j; }
    14 bool in_range(int i, int j) { return i >= 1 && i <= maxx && j >= 1 && j <= maxy; }
    15 void solve(){
    16     memset(C, 0, sizeof C);
    17     for(int i = 1, k = 1; i <= maxx; i++) for(int j = 1; j <= maxy; j++, k++){
    18         //the k-th column of the coefficient matrix
    19         for(int u = 0; u < 5; u++){
    20             int nx = i + dx[u], ny = j + dy[u], p = pos(nx, ny);
    21             if(in_range(nx, ny)) C[k][p] = 1;
    22         }
    23         C[k][maxm + 1] = A[i][j];
    24     }
    25     for(int i = 1; i <= maxm; i++){
    26         //eliminate for X(i)
    27         for(int j = i; j <= maxm; j++){
    28             //highlighting A[j][]
    29             if(C[j][i]){
    30                 swap(C[i], C[j]);
    31                 break;
    32             }
    33         }
    34         for(int j = i + 1; j <= maxm; j++){
    35             if(!C[j][i]) continue;
    36             for(int k = i; k <= maxm + 1; k++) C[j][k] ^= C[i][k];
    37         }
    38     }
    39     //retrieve the ans
    40     for(int i = maxm; i >= 1; i--){
    41         B[i] = C[i][maxm + 1];
    42         for(int j = i + 1; j <= maxm; j++) if(C[i][j]) B[i] ^= B[j];
    43     }
    44     for(int i = 1; i <= maxx; i++){
    45         printf("%d", B[pos(i, 1)]);
    46         for(int j = 2; j <= maxy; j++){
    47             int p = pos(i, j);
    48             printf(" %d", B[p]);
    49         }
    50         printf("
    ");
    51     }
    52 }
    53 
    54 int main(){
    55     freopen("in.txt", "r", stdin);
    56     int T, kase = 0;
    57     scanf("%d", &T);
    58     while(T--){
    59         printf("PUZZLE #%d
    ", ++kase);
    60         for(int i = 1; i <= maxx; i++) for(int j = 1; j <= maxy; j++) scanf("%d", &A[i][j]);
    61         solve();
    62     }
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    网络协议研究的工具-NS3
    指数ETF基金的组合分析方法初探
    小结量化投资之路(2013年写的旧帖再加工)
    金融计算的开源库——QuantLib 学习入门
    如何系统学习网络技术
    学好编程的几个方面
    C++的学习思路(总结以备忘)
    Think in SAS
    springSecurity + OAuth2 获取Token流程分析以及增加协议授权模式
    Redis主从复制、哨兵、Cluster三种模式
  • 原文地址:https://www.cnblogs.com/astoninfer/p/4830131.html
Copyright © 2020-2023  润新知