poj2947(高斯消元法解同余方程组)

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

题意:题目看着较复杂,实际上就是给了n个同余方程,解n个未知数。

思路:套高斯消元法的模板即可。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;

const int maxn=75;
int T,equ,var,MOD,a[maxn][maxn],x[maxn];
char s[75];

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;
}

void init(){
    memset(x,0,sizeof(x));
    for(int i=0;i<equ;++i){
        int k=i+1,t=1;
        for(int j=0;j<var;++j){
            a[i][j]=t;
            t=t*k%MOD;
        }
    }
}

int Gauss(){
    int k=0,LCM,ta,tb,tmp;
    for(int col=0;k<equ&&col<var;++k,++col){
        int max_r=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(a[i][col],a[k][col]);
            ta=LCM/a[i][col];
            tb=LCM/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)%MOD+MOD)%MOD;
            }
        }
    }
    for(int i=k;i<equ;++i){
        if(a[i][var]) 
            return -1;
    }
    if(k<var){
        return var-k;
    }
    for(int i=equ-1;i>=0;--i){
        tmp=a[i][var];
        for(int j=i+1;j<var;++j){
            if(!a[i][j]) continue;
            tmp-=a[i][j]*x[j];
            tmp=(tmp%MOD+MOD)%MOD;
        }
        while(tmp%a[i][i]!=0) tmp+=MOD;
        x[i]=(tmp/a[i][i])%MOD;
    }
    return 0;
}

int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d%s",&MOD,s);
        equ=var=strlen(s);
        init();
        for(int i=0;i<equ;++i){
            int t;
            if(s[i]=='*') t=0;
            else t=s[i]-'a'+1;
            a[i][var]=t;
        }
        Gauss();
        for(int i=0;i<var;++i){
            printf("%d",x[i]);
            if(i!=var-1) printf(" ");
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/FrankChen831X/p/11775509.html