poj1222 高斯消元

来源:互联网 发布:兼职网络编辑招聘 编辑:程序博客网 时间:2024/05/22 06:31

给出初始灯泡情况,翻转时会影响周围的4个+上自身

也就是mod2 的变换 

构造n*m个方程

解得答案



#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;typedef long long ll;const double pi=acos(-1.0);double eps=0.000001;const int maxn=35;int A[maxn][maxn];int b[maxn][maxn];const int mod=2;int n=5,m=6;int  x[maxn];//free_xint exgcd(int a,int b,int &x,int &y){    if(!b)    {        x = 1;        y = 0;        return a;    }    else    {        int r = exgcd(b,a%b,y,x);        y -= x * (a/b);        return r;    }}int lcm(int a,int b){    int x = 0, y =0;    return a / exgcd(a,b,x,y) * b;}int Gauss(int n,int m){    int r,c;    for(r=0,c=0; r<n && c<m; c++)    {        int maxr = r;        for(int i=r+1; i<n; i++) if(abs(A[i][c]) > abs(A[maxr][c])) maxr = i;        if(maxr != r) for(int i=c; i<=m; i++) swap(A[r][i],A[maxr][i]);        if(!A[r][c]) continue;        for(int i=r+1; i<n; i++) if(A[i][c])            {                int d = lcm(A[i][c],A[r][c]);                int t1 = d / A[i][c], t2 = d / A[r][c];                for(int j=c; j<=m; j++)                    A[i][j] = ((A[i][j] * t1 - A[r][j] * t2) % mod + mod) % mod;            }        r++;    }    for(int i=r; i<n; i++) if(A[i][m]) return -1;//无解    for(int i=r-1; i>=0; i--)    {        x[i] = A[i][m];        for(int j=i+1; j<m; j++)        {            x[i] = ((x[i] - A[i][j] * x[j]) % mod + mod) % mod;        }        int x1 = 0,y1 = 0;        int d = exgcd(A[i][i],mod,x1,y1);        x1 = ((x1 % mod) + mod) % mod;        x[i] = x[i] * x1 % mod;    }    return m-r; //free_x_Num,为0则有唯一解,否则不唯一}void Gauss_init(){    memset(A,0,sizeof A);    memset(x,0,sizeof x);}bool ok(int a,int b){    if(a>=0&&a<n&&b>=0&&b<m) return 1;    return 0;}/*guass会改变A数组和X数组,如多次调用需要每次复原A数组和X数组(memset)*///////////////////////debug/*int tmp[15][15];void out(){     for (int i=0; i<5; i++)    {        for (int j=0; j<6; j++)            printf("%d ",tmp[i][j]);        printf("\n");    }    printf("\n");}void ff( ){    for (int i=0; i<5; i++)        for (int j=0; j<6; j++)            scanf("%d",&tmp[i][j]);   out();    int x;    for (int i=0; i<5; i++)    {        for (int j=0; j<6; j++)        {            scanf("%d",&x);            if (!x)continue;               tmp[i][j]++;               tmp[i][j]%=2;            if (ok(i-1,j))tmp[i-1][j]++;            if (ok(i+1,j))tmp[i+1][j]++;            if (ok(i,j-1))tmp[i][j-1]++;            if (ok(i,j+1))tmp[i][j+1]++;            if (ok(i-1,j))tmp[i-1][j]%=2;            if (ok(i+1,j))tmp[i+1][j]%=2;            if (ok(i,j-1))tmp[i][j-1]%=2;            if (ok(i,j+1))tmp[i][j+1]%=2;        }    }    printf("\n");     out();}*/int aa[8][8];int main(){   // ff();    int cnt=1;    int t;    cin>>t;    while(t--)    {        n=5,m=6;        for (int i=0; i<n; i++)        {            for (int j=0; j<m; j++)                scanf("%d",&aa[i][j]);        }        Gauss_init();        for (int i=0; i<n; i++)        {            for (int j=0; j<m; j++)            {                A[i*m+j][i*m+j]+=1;                if (ok(i-1,j)) A[i*m+j][(i-1)*m+j]+=1;                if (ok(i+1,j)) A[i*m+j][(i+1)*m+j]+=1;                if (ok(i,j-1)) A[i*m+j][(i)*m+j-1]+=1;                if (ok(i,j+1)) A[i*m+j][(i)*m+j+1]+=1;                A[i*m+j][n*m]=1-(1-aa[i][j]);            }        }        int ret=  Gauss(n*m,n*m);        //  printf("debug:::%d\n",ret);        printf("PUZZLE #%d\n",cnt++);        int id=0;        for (int i=0; i<n; i++)        {            for (int j=0; j<m; j++)                printf("%d%c",x[id++],j==m-1?'\n':' ');        }    }}


0 0