码迷,mamicode.com
首页 > 其他好文 > 详细

高斯消元以poj1222为例

时间:2017-08-27 01:01:51      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:void   c代码   clu   eof   上下   nbsp   ++i   div   方程组   

【题目链接】

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

【题目大意】
  5*6的一个由灯组成的方阵 操作一个灯 周围的上下左右四个灯会发生相应变化 即由灭变亮 由亮变灭 问如何操作使灯全亮

【题解】

  对于每个灯可以列出一个方程

  Lk表示第 k 个灯的初始终状态 

  ai:表示第 i 个开关是否对 L有影响

  xj:表示第 j 个开关的状态

  L1 XOR  a*xXOR  a2*x2  XOR  a3*x3 XOR …… XOR  a29*x29 XOR  a30x30 = 0

  L2 XOR  a*xXOR  a2*x2  XOR  a3*x3 XOR …… XOR  a29*x29 XOR  a30x30 = 0  

  ……

  L30 XOR  a*xXOR  a2*x2  XOR  a3*x3 XOR …… XOR  a29*x29 XOR  a30x30 = 0 

  解上述异或方程组即可得到答案。

  为了方便求解,可将上述方程组变形,两边同时异或L (由于0^a = a),得:

   a*xXOR  a2*x2  XOR  a3*x3 XOR …… XOR  a29*x29 XOR  a30x30 = L1

   a*xXOR  a2*x2  XOR  a3*x3 XOR …… XOR  a29*x29 XOR  a30x30 = L2

  ……

   a*xXOR  a2*x2  XOR  a3*x3 XOR …… XOR  a29*x29 XOR  a30x30 = L30

 

   【ac代码】

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 using namespace std;
  5 
  6 int a[35][35];    //增广矩阵 
  7 int x[35];        //线性方程组的解 
  8 int equ;        //方程个数 
  9 int var;        //变量个数 
 10 
 11 void init()
 12 {
 13     memset(x, 0, sizeof(x));
 14     memset(a, 0, sizeof(a));
 15 } 
 16 
 17 void Gauss()
 18 {
 19     int row, col, i, j;
 20     row = col = 0;
 21     
 22     while(row<equ && col<var)
 23     {
 24         for(i=row; i<equ; ++i)    //选出row~equ行中第一个为1的那一行 
 25         {
 26             if(a[i][col] != 0) break;
 27         }
 28         if(i != row)    //两行交换    
 29         {
 30             for(j=col;j<=var;++j)
 31             {
 32                 swap(a[row][j], a[i][j]);
 33             } 
 34         }
 35         if(a[row][col]==0)    //无法消元,继续下一个变量 
 36         {
 37             ++col;
 38             continue;
 39         } 
 40         
 41         for(int i=row+1;i<equ;++i)    //消元
 42         {
 43             if(a[i][col]==0) continue;
 44             for(int j=col;j<=var;++j)
 45             {
 46                 a[i][j] ^= a[row][j];
 47             }
 48         } 
 49         ++row;
 50         ++col;    
 51     }
 52     
 53     for(i=var-1;i>=0;--i)    //回代求解 
 54     {
 55         x[i] = a[i][var];
 56         for(j=i+1;j<var;++j)
 57         {
 58             x[i] ^= (a[i][j]&&x[j]);    //回代关键步骤 
 59         } 
 60     }
 61 }
 62 
 63 int main()
 64 {
 65     int t;
 66     int num;
 67     scanf("%d", &t);
 68     for(int item=1; item<=t; ++item)
 69     {
 70         init();
 71         for(int i=0;i<30;++i)
 72         {
 73             scanf("%d", &a[i][30]);
 74         }
 75         
 76         for(int i=0;i<5;++i)        //确定方程组的系数 
 77         {                            //a[i][j]的意义:第j个开关能否控制第i个灯 
 78             for(int j=0;j<6;++j)
 79             {
 80                 int num = i*6+j;
 81                 a[num][num] = 1;
 82                 if(i>=1)
 83                 {
 84                     a[num-6][num] = 1;
 85                 }
 86                 if(i<=3)
 87                 {
 88                     a[num+6][num] = 1;
 89                 }
 90                 if(j-1 >= 0)
 91                 {
 92                     a[num-1][num] = 1;
 93                 }
 94                 if(j+1 <= 5)
 95                 {
 96                     a[num+1][num] = 1;
 97                 }
 98             }
 99         }
100         
101         equ = 30;
102         var = 30;
103         
104         Gauss();
105         printf("PUZZLE #%d\n", item);
106         for(int i=0;i<30;++i)
107         {
108             if(i%6==5)            //控制每行输出6个 
109             {
110                 printf("%d", x[i]);
111                 printf("\n");
112             }
113             else
114             {
115                 printf("%d ", x[i]);
116             }
117         }
118     }
119     return 0;
120 } 

 

   【模板】:后续更新

高斯消元以poj1222为例

标签:void   c代码   clu   eof   上下   nbsp   ++i   div   方程组   

原文地址:http://www.cnblogs.com/chcaxi/p/7436104.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!