高斯消元 EXTENDED LIGHTS OUT POJ

来源:互联网 发布:淘宝人工刷流量网站 编辑:程序博客网 时间:2024/05/12 06:22

板子题,快记下来~

题意:一个5*6的网格,然后每个格子里有一个按钮,如果点击这个按钮,那么这个按钮四周包括自己就会翻转,给一个初始状态(01表示按钮的状态),问如果要翻转成全是0的方法

分析:之前做过暴力版的,就是枚举第一行,然后之后的状态都确定下来了~
高斯也可以来一波
大概意思就是,将每个格子的翻转情况设为xi,然后列方程,解方程,就可以得到答案了。
然后这里还有一个小技巧,用的异或操作,因为数据是01,相当于%2,%2的加法就相当于异或

#define ll long long#define mem(a,b) memset(a,b,sizeof(a))const int maxn = 100;int a[maxn][maxn],x[maxn];void guass(int row,int col){    for(int i=0;i<=col;i++)        x[i]=0;    int r=0,c=0,t=0;    for(;r<row&&c<col;r++,c++){     int k=r;     for(int i=r+1;i<row;i++)     {        if(a[i][c]>a[k][c])        {k=i;}     }     if(k!=r)     {        for(int i=r;i<=col;i++)//这里要加等于号....        {            swap(a[k][i],a[r][i]);        }     }    if(!a[r][c]) {r--;continue;}    for(int i=r+1;i<row;i++)    {        if(a[i][c]!=0)        {            for(int j=c;j<=col;j++)                a[i][j]=a[i][j]^a[r][j];        }    }   }   for(int i=col-1;i>=0;i--)   {       x[i]=a[i][col];       for(int j=i+1;j<col;j++)       {           if(a[i][j]!=0)           {               x[i]=x[i]^(a[i][j]&&x[j]);           }       }   }   return ;}int main(){    int T,case1=1;    scanf("%d",&T);    while(T--)    {        memset(x,0,sizeof(x));        memset(a,0,sizeof(a));        for(int i=0;i<30;i++)        {            int x;            scanf("%d",&x);            a[i][30]=x;        }        for(int i=0;i<30;i++)        {            a[i][i]=1;            if(i%6)  a[i-1][i]=1;            if(i%6!=5) a[i+1][i]=1;            if(i>5)  a[i-6][i]=1;            if(i<24) a[i+6][i]=1;        }        guass(30,30);        printf("PUZZLE #%d\n",case1++);        for(int i=0;i<30;i++)        {            if(i==0) printf("%d",x[i]);            else if(i%6==0) {printf("\n");printf("%d",x[i]);}            else printf(" %d",x[i]);        }        printf("\n");    }    return 0;}
原创粉丝点击