zoukankan      html  css  js  c++  java
  • 高斯消元法 专题

    大神博客

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

    入门题:

    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
    ",a)
    #define ptlld(a) printf("%I64d
    ",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("
    ");
        }
    }
    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
    ",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?'
    ':' ');
            }
        }
    }
    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
    ",a)
    #define ptlld(a) printf("%I64d
    ",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("
    ");
        }
    }
    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
    ",cnt);
            rep(i,0,n-1)
            {
                rep(j,0,m-1)
                {
                    while(x[i*m+j])
                    {
                        printf("%d %d
    ",i+1,j+1);
                        x[i*m+j]--;
                    }
                }
            }
        }
    }
    不为失败找借口,只为成功找方法
  • 相关阅读:
    Heritrix 3.1.0 源码解析(二十五)
    Heritrix 3.1.0 源码解析(二十八)
    获取某年某月的第一天和最后一天的Sql Server函数
    C# ToString()用法汇总
    数据库隐式类型转换
    sql server 中 SET identity_insert on
    Linq To DataTable
    ASP.NET Session详解[转载]
    CSS overflow 属性
    HTML相对路径(Relative Path)和绝对路径(Absolute Path)
  • 原文地址:https://www.cnblogs.com/youmi/p/5719940.html
Copyright © 2011-2022 走看看