[Gauss]POJ1222 EXTENDED LIGHTS OUT

题意:给一个5*6的矩阵

1代表该位置的灯亮着, 0代表该位置的灯没亮

按某个位置的开关,可以同时改变 该位置 以及 该位置上方、下方、左方、右方, 共五个位置的灯的开、关(1->0, 0->1)

问能否将所有的灯关闭 若能 输出需要按哪些地方; 不能输出-1

 

高斯消元的入门题。

每个位置可以列出一个方程, 列出增广矩阵:

  每个位置可以形成增广矩阵的一行, 每行都有30个系数 分别代表(0到29号灯), 将 可以影响该位置改变的 位置(自己、上、下、左、右)对应的置1, 其余置0

  这样就形成了30*30的系数矩阵。

  将初始状态置入最后一列 就形成了增广矩阵

 

接下来只要解方程组即可。

化成约化阶梯后最后一列即为该方程组的解。

 

P.s. 需要注意的是:因为是矩阵表示的是灯的开关状态,所以解的过程中不应出现0、1以外的其余数字 即 01方程 用异或求解

 

[Gauss]POJ1222 EXTENDED LIGHTS OUT
  1 int a[300][300];  // 增广矩阵

  2 int x[300];  //

  3 int free_x[300]; // 标记是否为自由未知量

  4 

  5 int n, m;

  6 void debug()

  7 {

  8     for(int i=0;i<n*n;i++)

  9     {

 10         for(int j=0;j<n*n;j++)

 11             printf("%d ", a[i][j]);

 12         printf("\n");

 13     }

 14 }

 15 

 16 void Gauss(int n, int m) // n个方程 m个未知数 即 n行m+1列

 17 {

 18     //转换为阶梯形式

 19     int col=0, k, num=0;

 20     for(k=0;k<n && col<m;k++, col++)

 21     {//枚举行

 22         int max_r=k;

 23         for(int i=k+1;i<n;i++)//找到第col列元素绝对值最大的那行与第k行交换

 24             if(abs(a[i][col])>abs(a[max_r][col]))

 25                 max_r=i;

 26         if(max_r!=k)// 与第k行交换

 27             for(int j=col;j<m+1;j++)

 28                 swap(a[k][j], a[max_r][j]);

 29         if(!a[k][col])// 说明该col列第k行以下全是0了

 30         {

 31             k--;

 32             free_x[num++]=col;

 33             continue;

 34         }

 35         for(int i=k+1;i<n;i++)// 枚举要删除的行

 36             if(a[i][col])

 37                 for(int j=col;j<m+1;j++)

 38                     a[i][j]^=a[k][j];

 39     }

 40 

 41 //    debug();

 42 //    printf("%d %d\n", col, k);

 43 //

 44 //    for(int i=k;i<n;i++)

 45 //        if(a[i][col])

 46 //            return -1; // 无解

 47 

 48 //    if(k<m)   //m-k为自由未知量个数

 49 //    {

 50 //        int stat=1<<(m-k);

 51 //        int ans=INT_MAX;

 52 //        for(int i=0;i<stat;i++)

 53 //        {

 54 //            int cnt=0;

 55 //            for(int j=0;j<m-k;j++)

 56 //                if(i&(1<<j))

 57 //                {

 58 //                    x[free_x[j]]=1;

 59 //                    cnt++;

 60 //                }

 61 //                else

 62 //                    x[free_x[j]]=0;

 63 //            for(int j=k-1;j>=0;j--)

 64 //            {

 65 //                int tmp;

 66 //                for(tmp=j;tmp<m;tmp++)

 67 //                    if(a[j][tmp])

 68 //                        break;

 69 //                x[tmp]=a[j][m];

 70 //                for(int l=tmp+1;l<m;l++)

 71 //                    if(a[j][l])

 72 //                        x[tmp]^=x[l];

 73 //                cnt+=x[tmp];

 74 //            }

 75 //            if(cnt<ans)

 76 //                ans=cnt;

 77 //        }

 78 //        return ans;

 79 //    }

 80 //

 81     //  唯一解 回代

 82     for(int i=m-1;i>=0;i--)

 83     {

 84         x[i]=a[i][m];

 85         for(int j=i+1;j<m;j++)

 86             x[i]^=(a[i][j] && x[j]);

 87     }

 88 //    int ans=0;

 89 //    for(int i=0;i<n*n;i++)

 90 //        ans+=x[i];

 91 //    return ans;

 92 }

 93 

 94 

 95 void init()

 96 {

 97     n=5, m=6;

 98     memset(a, 0, sizeof(a));

 99     memset(x, 0, sizeof(x));

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

101         for(int j=0;j<m;j++)

102         {

103             int t=i*m+j;

104             a[t][t]=1;

105             if(i>0)

106                 a[(i-1)*m+j][t]=1;

107             if(i<n-1)

108                 a[(i+1)*m+j][t]=1;

109             if(j>0)

110                 a[i*m+j-1][t]=1;

111             if(j<m-1)

112                 a[i*m+j+1][t]=1;

113         }

114 }

115 

116 int main()

117 {

118     int t, ca=1;

119     scanf("%d", &t);

120     while(t--)

121     {

122         init();

123         for(int i=0;i<n*m;i++)

124             scanf("%d", &a[i][n*m]);

125         printf("PUZZLE #%d\n", ca++);

126         Gauss(n*m, n*m);

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

128             for(int j=0;j<m;j++)

129             {

130                 printf("%d", x[i*m+j]);

131                 if(j==5)

132                     printf("\n");

133                 else

134                     printf(" ");

135             }

136     }

137     return 0;

138 }
POJ 1222

 

你可能感兴趣的:(extend)