poj 1222(高斯消元法求解。。。。)

捣鼓了一整天。。。。终于弄明白了这个怎么来求解。。。。

这个题的对立面就是说给你一个全熄的矩阵。。。经过一系列变化。。。让它跟题中输入的初始矩阵相等就可以了(mod 2 相当与异或所以可以这样来)。。。。没按下一个按钮相当与加上一个

0 1 0 
1 1 1 
0 1 0
这样的矩阵。。。。当然了边界情况也是需要考虑进去的。。。。自己可以写出相应的要加上的矩阵的吧。。。。。

设x表示是否按下,a表示要加上的矩阵。。。b表示初始的矩阵。。。则这个题可以表示为。。。

x(1,1)*a(1,1)+x(1,2)*a(1,2)+。。。。+x(5,6)*a(5,6)=b;

然后把x。。a。。b。。都化成一维的就可以了。。。。。而且这个题一定有解(题目给出的)所以很多消元的时候的细节可以直接跳过了。。。嗨皮。。。。



#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int m[32][32], ans[32];
void gauss(){
    int i,j,k;
    for (k = 1; k <= 30; k++) {
        i = k;
        while((m[i][k] == 0) && (i <= 30))
            i++;
        if(i > k) {
            for(j = 1; j <= 31; j++)
                swap(m[i][j], m[k][j]);
        }
        for(i = 1; i <= 30; i++) {
            if(i != k && m[i][k])
                for(j=1; j<= 31; j++)
                    m[i][j] ^= m[k][j];
        }
    }
}
int main() {
    int n, i, j, k;
    scanf("%d", &n);
    for (i = 1; i <= n; i++) {
        memset(m, 0, sizeof (m));
        for (j = 1; j <= 30; j++) {
            scanf("%d", &m[j][31]);
            ans[j] = 0;
        }
        for (j = 1; j <= 30; j++) {
            m[j][j] = 1;
            if (j % 6 != 1) m[j - 1][j] = 1;
            if (j % 6 != 0) m[j + 1][j] = 1;
            if (j >= 7) m[j - 6][j] = 1;
            if (j <= 24) m[j + 6][j] = 1;
        }
        gauss();
        for(j = 1; j <= 30; j++)
            if(m[j][31]){
                for(k=1; k <= 30 && !m[j][k]; k++);
                if(k <= 30)
                    ans[j] = m[j][31];
            }
        printf("PUZZLE #%d\n",i);
        for(j=1; j<=30; j++){
            printf("%d",ans[j]);
            if(j%6==0)
                printf("\n");
            else
                printf(" ");
        }
    }
    return 0;
}


你可能感兴趣的:(poj 1222(高斯消元法求解。。。。))