大神博客

今年多校遇到一道高斯消元模板题,当时没做,主要原因还是太菜,简单题都没做完。。。。。赛后回过头来刷题解说是高斯消元(这一直都是队友负责的),所以我还是一脸懵逼。队友说这题完全可以暴力,我只有一个字:哦。。。。。。。

入门题:

poj 1222 EXTENDED LIGHTS OUT

思路:已经有很多相关的博客写过题解,我就不累述了。关键的就是:

  1. A【30】(初始状态矩阵),B【30】【30】(根据操作列的方程组),X(方【30】程的解),由题意得A+BX=0,等价于A=BX;
  2. 一个灯最后的状态由上下左右和自身的操作决定的,而我们的x【30】解就是30个按钮的操作次数;比如第一个格子(0,0),他的状态由(0,0)(0,1),(1,0)决定,所以可列方程x(0*6+0)+x(0*6+1)+x(1*6+0)=原始状态
/**************************************************************
    Problem:poj 1222 EXTENDED LIGHTS OUT
    User: youmi
    Language: C++
    Result: Accepted
    Time:16MS
    Memory:660K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep(i,from,to) for(int i=from;i<=to;i++)
#define irep(i,to,from) for(int i=to;i>=from;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define eps 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl
const double pi=4*atan(1.0);

using namespace std;
typedef long long ll;
template <typename T> inline void read(T &n)
{
    char c; int flag = 1;
    for (c = getchar(); !(c >= '0' && c <= '9' || c == '-'); c = getchar()); if (c == '-') flag = -1, n = 0; else n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0'; n *= flag;
}
template<class T> inline T gcd(T a,T b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
template<class T> inline T lcm(T a,T b)
{
    return a*b/gcd(a,b);
}
int Pow(int base, ll n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************
int n,m;
const int maxn=30+10;
int a[maxn][maxn];
int x[maxn];
int fre[maxn];
int index;
int kx[]={1,-1,0,0};
int ky[]={0,0,1,-1};
void debug(int rw,int cl)
{
    rep(i,0,rw-1)
    {
        rep(j,0,cl-1)
            printf("%d ",a[i][j]);
        printf("\n");
    }
}
bool is_out(int xx,int yy)
{
    if(xx<0||yy<0||xx>4||yy>5)
        return true;
    return false;
}
void init()
{
    memset(fre,1,sizeof(fre));
    zeros(x);
    zeros(a);
}
int gauss(int rw,int cl)
{
    int i,j,k;
    int mx=0;
    for(i=0,j=0;i<rw&&j<cl-1;i++,j++)
    {
        mx=i;
        for(k=i;k<rw;k++)
        {
            if(abs(a[k][j])>abs(a[mx][j]))
                mx=k;
        }
        if(mx!=i)
        {
            for(k=j;k<cl;k++)
                swap(a[mx][k],a[i][k]);
        }
        if(a[i][j]==0)
        {
            i--;
            continue;
        }
        for(k=i+1;k<rw;k++)
        {
            if(a[k][j]!=0)
            {
                /**int Lcm=lcm(a[k][j],a[i][j]);
                int ta=Lcm/a[i][j],tb=Lcm/a[k][j];*/
                for(int t=j;t<cl;t++)
                {
                    //a[k][t]=a[k][t]*ta-a[i][t]*tb;
                    a[k][t]^=a[i][t];
                }
            }
        }
    }
    //debug(30,31);
    /**for(k=i+1;k<rw;k++)
    {
        if(a[k][j]!=0)
            return -1;//no solution
    }
    if(i<rw)//infinite solution
    {
        for(k=i-1;k>=0;k--)
        {
            int num=0;
            for(int t=0;t<cl;t++)
            {
                if(a[k][t]!=0&&fre[t])
                    num++,index=t;
            }
            if(num>1)
                continue;
            int temp=a[k][cl-1];
            for(int t=0;t<cl-1;t++)
                if(a[k][t]!=0&&index!=t)
                    temp-=a[k][t]*x[t];
            x[index]=temp/a[k][index];
            fre[index]=0;
        }
        return rw-i;
    }*/
    for(k=rw-1;k>=0;k--)
    {
        int temp=a[k][cl-1];
        for(int t=k+1;t<cl-1;t++)
            temp^=a[k][t]&&x[t];
        /**if(temp%a[k][k])
            return -2;// float answer*/
        x[k]=temp&&a[k][k];
    }
    return 0;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int T_T;
    scanf("%d",&T_T);
    for(int kase=1;kase<=T_T;kase++)
    {
        printf("PUZZLE #%d\n",kase);
        init();
        int temp=0;
        rep(i,0,4)
            rep(j,0,5)
                sc(a[i*6+j][30]);
        rep(i,0,4)
        {
            rep(j,0,5)
            {
                a[temp][i*6+j]=1;
                rep(k,0,3)
                {
                    if(!is_out(i+kx[k],j+ky[k]))
                        a[temp][(i+kx[k])*6+j+ky[k]]=1;
                }
                temp++;
            }
        }
        //debug(30,31);
        gauss(30,31);
        rep(i,0,4)
        {
            rep(j,0,5)
                printf("%d%c",x[i*6+j],j==5?'\n':' ');
        }
    }
}
View Code

 

hdu 5755 Gambler Bo

solution: 一个mod3版本的开关灯问题,对每个格子分别设操作了xi次,那么就可以列出一个n*m的方程组,然后高斯消元就可以了

/**************************************************************
    Problem:hdu 5755 Gambler Bo
    User: youmi
    Language: C++
    Result: Accepted
    Time:483MS
    Memory:4828K
    solution:   一个mod3版本的开关灯问题,对每个格子分别设操作了xi次,
                那么就可以列出一个n*m的方程组,然后高斯消元就可以了
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep(i,from,to) for(int i=from;i<=to;i++)
#define irep(i,to,from) for(int i=to;i>=from;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define eps 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl
const double pi=4*atan(1.0);

using namespace std;
typedef long long ll;
template <typename T> inline void read(T &n)
{
    char c; int flag = 1;
    for (c = getchar(); !(c >= '0' && c <= '9' || c == '-'); c = getchar()); if (c == '-') flag = -1, n = 0; else n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0'; n *= flag;
}
template<class T> inline T gcd(T a,T b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
template<class T> inline T lcm(T a,T b)
{
    return a*b/gcd(a,b);
}
int Pow(int base, ll n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************
int n,m;
const int maxn=900+10;
int a[maxn][maxn];
int x[maxn];
int fre[maxn];
int index;
int kx[]={1,-1,0,0};
int ky[]={0,0,1,-1};
void debug(int rw,int cl)
{
    rep(i,0,rw-1)
    {
        rep(j,0,cl-1)
            printf("%d ",a[i][j]);
        printf("\n");
    }
}
bool is_out(int xx,int yy,int rw,int cl)
{
    if(xx<0||yy<0||xx>=rw||yy>=cl)
        return true;
    return false;
}
void init()
{
    memset(fre,1,sizeof(fre));
    zeros(x);
    zeros(a);
}
int gauss(int rw,int cl)
{
    int i,j,k;
    int mx=0;
    for(i=0,j=0;i<rw&&j<cl-1;i++,j++)
    {
        mx=i;
        for(k=i;k<rw;k++)
        {
            if(abs(a[k][j])>abs(a[mx][j]))
                mx=k;
        }
        if(mx!=i)
        {
            for(k=j;k<cl;k++)
                swap(a[mx][k],a[i][k]);
        }
        if(a[i][j]==0)
        {
            i--;
            continue;
        }
        for(k=i+1;k<rw;k++)
        {
            if(a[k][j]!=0)
            {
                int Lcm=lcm(a[k][j],a[i][j]);
                int ti=Lcm/a[i][j],tk=Lcm/a[k][j];
                for(int t=j;t<cl;t++)
                {
                    a[k][t]=((a[k][t]*tk-a[i][t]*ti)%3+3)%3;
                }
            }
        }
    }
    //debug(rw,cl);
    for(k=rw-1;k>=0;k--)
    {
        int temp=a[k][cl-1]%3;
        for(int t=k+1;t<cl-1;t++)
            temp=((temp-a[k][t]*x[t])%3+3)%3;
        x[k]=temp*a[k][k]%3;
    }
    return 0;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int T_T;
    scanf("%d",&T_T);
    for(int kase=1;kase<=T_T;kase++)
    {
        sc2(n,m);
        init();
        int temp=0;
        rep(i,0,n-1)
            rep(j,0,m-1)
            {
                sc(a[i*m+j][n*m]);
                a[i*m+j][n*m]=(3-a[i*m+j][n*m])%3;
            }
        rep(i,0,n-1)
        {
            rep(j,0,m-1)
            {
                a[temp][i*m+j]=2;
                rep(k,0,3)
                {
                    if(!is_out(i+kx[k],j+ky[k],n,m))
                        a[temp][(i+kx[k])*m+j+ky[k]]=1;
                }
                temp++;
            }
        }
        gauss(n*m,n*m+1);
        int cnt=0;
        rep(i,0,n-1)
            rep(j,0,m-1)
                if(x[i*m+j])
                    cnt+=x[i*m+j];
        printf("%d\n",cnt);
        rep(i,0,n-1)
        {
            rep(j,0,m-1)
            {
                while(x[i*m+j])
                {
                    printf("%d %d\n",i+1,j+1);
                    x[i*m+j]--;
                }
            }
        }
    }
}

 

posted on 2016-07-29 23:29  中子星  阅读(205)  评论(0编辑  收藏  举报