zoukankan      html  css  js  c++  java
  • (模板)poj2947(高斯消元法解同余方程组)

    题目链接:https://vjudge.net/problem/POJ-2947

    题意:转换题意后就是已知m个同余方程,求n个变量。

    思路:

      值得学习的是这个模板里消元用到lcm的那一块。注意题目输出的答案在[3,9]之间。

    AC代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    
    const int maxn=305;
    int n,m,a[maxn][maxn],x[maxn];
    char s1[10],s2[10];
    
    int gcd(int a,int b){
        return b?gcd(b,a%b):a;
    }
    
    int lcm(int a,int b){
        return a/gcd(a,b)*b;  //先除后乘
    }
    
    // 高斯消元法解方程组(Gauss-Jordan elimination).(
    //-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由变元的个数)
    //有equ个方程,var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
    int Gauss(int equ,int var){
        int k,max_r,col=0,ta,tb,LCM,temp;
        for(int i=0;i<var;++i){
            x[i]=0;
        }
        for(k=0;k<equ&&col<var;++k,++col){
            max_r=k;
            //找系数绝对值最大的那一行与第k行交换
            for(int i=k+1;i<equ;++i){
                if(abs(a[i][col])>abs(a[max_r][col]))
                    max_r=i;
            }
            if(max_r!=k){
                for(int i=col;i<var+1;++i)
                    swap(a[max_r][i],a[k][i]);
            }
            if(!a[k][col]){
                --k;
                continue;
            }
            for(int i=k+1;i<equ;++i){
                if(!a[i][col]) continue;
                LCM=lcm(abs(a[i][col]),abs(a[k][col]));
                ta=LCM/abs(a[i][col]);
                tb=LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0) tb=-tb; //异号的情况是相加
                for(int j=col;j<var+1;++j){
                    a[i][j]=((a[i][j]*ta-a[k][j]*tb)%7+7)%7;
                }
            }
        }
        //无解的情况
        for(int i=k;i<equ;++i){
            if(a[i][col]) return -1;
        }
        //无穷解的情况
        if(k<var){    
            return var-k;   //返回自由变元的个数
        }
        //唯一解的情况,增广矩阵中形成严格的上三角阵
        for(int i=var-1;i>=0;--i){
            temp=a[i][var];
            for(int j=i+1;j<var;++j){
                if(!a[i][j]) continue;
                temp-=a[i][j]*x[j];
                temp=(temp%7+7)%7;
            }
            while(temp%a[i][i]!=0) temp+=7;
            x[i]=(temp/a[i][i])%7;
        }
        return 0;
    }
    
    int tran(char *s){
        if(strcmp(s,"MON")==0) return 1;
        else if(strcmp(s,"TUE")==0) return 2;
        else if(strcmp(s,"WED")==0) return 3;
        else if(strcmp(s,"THU")==0) return 4;
        else if(strcmp(s,"FRI")==0) return 5;
        else if(strcmp(s,"SAT")==0) return 6;
        else return 7;
    }
    
    int main(){
        while(scanf("%d%d",&n,&m),n||m){
            memset(a,0,sizeof(a));
            for(int i=0;i<m;++i){
                int k;
                scanf("%d%s%s",&k,s1,s2);
                a[i][n]=((tran(s2)-tran(s1)+1)%7+7)%7;
                while(k--){
                    int t;
                    scanf("%d",&t);
                    --t;
                    ++a[i][t];
                    a[i][t]%=7;
                }
            }
            int ans=Gauss(m,n);
            if(ans==0){
                for(int i=0;i<n;++i)
                    if(x[i]<=2) x[i]+=7;
                for(int i=0;i<n-1;++i)
                    printf("%d ",x[i]);
                printf("%d
    ",x[n-1]);
            }
            else if(ans==-1){
                printf("Inconsistent data.
    ");
            }
            else{
                printf("Multiple solutions.
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    Docker 简单部署 ElasticSearch
    Anaconda更新失败简单解决[CondaHTTPError: HTTP 000 CONNECTION FAILED for url]
    TermKit的新一代Mac终端,在Ubuntu 11.04 轻松安装TermKit
    Linux下如何测试网速
    centos7安装yum
    Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
    yum 安装指定版本Docker
    如何在 Apache Hive 中解析 Json 数组
    unzip解压失败( cannot find zipfile directory)
    Linux 定时任务crontab_014
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/11775127.html
Copyright © 2011-2022 走看看