• poj1222 EXTENDED LIGHTS OUT 高斯消元解异或方程组 模板


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

    题意:给出一个5*6的图,每个灯泡有一个初始状态,1表示亮,0表示灭。每对一个灯泡操作时,会影响周围的灯泡改变亮灭,问如何操作可以使得所有灯泡都关掉。

    思路:因为每盏灯,如果操作两次就相当于没有操作,所以相当于(操作次数)%2,即异或操作。

    考虑一个2*3的图,最后需要的状态是 :,如果初始状态为:。对这两个矩阵的每个数字做异或操作可以得到线性方程组每个方程的答案。

    总共6盏灯,0-5。那么可以列出6个方程。

    对于第0盏灯,会影响到它的是第0, 1, 3盏灯,因此可以列出方程1*x0 + 1*x1 + 0*x2 + 1*x3 + 0*x4 + 0*x5= 0。

    对于第1盏灯,会影响到它的是第0, 1, 2,4盏灯,因此可以列出方程1*x0 + 1*x1 + 1*x2 + 0*x3 + 1*x4 + 0*x5 = 1。

    对于第2盏灯,会影响到它的是第1, 2, 5盏灯,因此可以列出方程0*x0 + 1*x1 + 1*x2 + 0*x3 + 0*x4 + 1*x5 = 0。

    .....

    所以最后可以列出增广矩阵:

    然后用高斯消元求这个矩阵的解就可以了。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <cmath>
     5 using namespace std;
     6 #define maxn 8
     7 int a[maxn*maxn][maxn*maxn];
     8 int x[maxn*maxn];
     9 int mp[maxn][maxn];
    10 void init()
    11 {
    12     memset(a, 0, sizeof(a));
    13     for(int i = 0; i < 5; i++)
    14     {
    15         for(int j = 0; j < 6; j++)
    16         {
    17             int pos = i*6+j;
    18             a[pos][pos] = 1;
    19             if(i > 0) a[pos][(i-1)*6+j] = 1;
    20             if(i < 4) a[pos][(i+1)*6+j] = 1;
    21             if(j > 0) a[pos][i*6+j-1] = 1;
    22             if(j < 5) a[pos][i*6+j+1] = 1;
    23         }
    24     }
    25 }
    26 void Gauss(int n, int m)
    27 {
    28     memset(x, 0, sizeof(x));
    29     int r, c;
    30     for(r = 0, c = 0; r < n && c < m; r++, c++)
    31     {
    32         int max_r = r;
    33         for(int i = r+1; i < n; i++)
    34         {
    35             if(fabs(a[i][c]) > fabs(a[max_r][c])) max_r = i;
    36         }
    37         if(a[max_r][c] == 0) {r--; continue;}
    38         if(max_r != r)
    39         {
    40             for(int i = c; i < m+1; i++) swap(a[max_r][i], a[r][i]);
    41         }
    42         
    43         for(int i = r+1; i < n; i++)
    44         {
    45             if(a[i][c] == 0) continue;
    46             for(int j = c; j < m+1; j++) a[i][j] ^= a[r][j];
    47         }
    48     }
    49     
    50     for(int i = m-1; i >= 0; i--)
    51     {
    52         x[i] = a[i][m];
    53         for(int j = i+1; j < m; j++)
    54         {
    55             x[i] ^= (a[i][j] && x[j]);
    56         }
    57     }
    58 }
    59 int main() 
    60 {
    61    // freopen("in.txt", "r", stdin);
    62     int T;
    63     scanf("%d", &T);
    64     int cast = 0;
    65     while(T--)
    66     {
    67         cast++;
    68         init();
    69         for(int i = 0; i < 5; i++)
    70         {
    71             for(int j = 0; j < 6; j++)
    72             {
    73                 scanf("%d", &a[i*6+j][30]);
    74             }
    75         }
    76         Gauss(30, 30);
    77         printf("PUZZLE #%d
    ", cast);
    78         for(int i = 0; i < 5; i++)
    79         {
    80             for(int j = 0; j < 6; j++)
    81             {
    82                 if(j == 0) printf("%d", x[i*6+j]);
    83                 else printf(" %d", x[i*6+j]);
    84             }
    85             printf("
    ");
    86         }
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    Silverlight C# 游戏开发:Flyer05与什么什么进行搏斗
    Silverlight C# 游戏开发:Flyer07做一个有开始的游戏
    Silverlight C# 游戏开发:面向对象在游戏中的实例(一)
    Silverlight C# 游戏开发:面向对象在游戏中的实例(二)
    Silverlight C# 游戏开发:Flyer06小小的改进让游戏更有趣
    linux网络命令ip\route\links回顾
    Google Style的C++编码规范
    TCP/IP协议和IP组播的视频传输
    Multicast server and client in Python
    用户profile中umask码的含义详解(默认是022)
  • 原文地址:https://www.cnblogs.com/titicia/p/5396997.html
Copyright © 2020-2023  润新知