POJ_2065 SETI 同余高斯消元

Posted dybala21

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ_2065 SETI 同余高斯消元相关的知识,希望对你有一定的参考价值。

一、题目

   SETI 

二、分析  

  给定一个模数,一串字符串,字符串长度为N,相当于是N个方程的答案,而这N个方程中有N个未知数,要求的就是这N个未知数的值,很显然的高斯消元,遇到模数和除法,用逆元就好。

三、AC代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;
#define ll long long
#define Min(a,b) ((a)>(b)?(b):(a))
#define Max(a,b) ((a)>(b)?(a):(b))
const int maxn = 1e2;
int p;
char s[maxn];
int a[maxn][maxn], x[maxn];
int n, equ, var;

int gcd(int a, int b)

    return b == 0 ? a : gcd(b, a%b);


int lcm(int a, int b)

    return a / gcd(a, b) * b;


int inv(int a, int m)

    if(a == 1)
        return 1;
    return inv(m%a, m) * (m - m/a)%m;


int getInt(char c)

    if(c == ‘*‘)
        return 0;
    else
        return c - ‘a‘ + 1;


int Gauss()

    int k, col, max_r;
    for(k = 0, col = 0; k < equ && col < var; k++, col++)
    
        max_r = k;
        for(int i = k + 1; i < equ; i++)
        
            if(fabs(a[i][col]) > fabs(a[max_r][col]))
                max_r = i;
        
        if(a[max_r][col] == 0)
        
            k--;
            continue;
        
        if(max_r != k)
        
            for(int i = col; i < (var + 1); i++)
            
                swap(a[max_r][i], a[k][i]);
            
        
        //消元
        for(int i = k + 1; i < equ; i++)
        
            if(a[i][col] != 0)
            
                int LCM = lcm( fabs(a[i][col]), fabs(a[k][col]));
                int ta = LCM / fabs(a[i][col]);
                int tb = LCM / fabs(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) % p + p)%p;
                    a[i][col] = 0;
                
            
        
    
    for(int i = k; i < equ; i++)
        
            if(a[i][var+1] != 0)
                return -1;  //无解
        
        //多解
        if(k < var)
            return var - k;
        for(int i = var - 1; i >= 0; i--)
        
            int tmp = a[i][var];
            for(int j = i + 1; j < var ;j++)
            
                if(a[i][j] != 0)
                
                    tmp -= a[i][j] * x[j];
                
                tmp = (tmp % p + p) % p;
            
            x[i] = (tmp * inv(a[i][i], p)) % p;
        


void solve()

    equ = n, var = n;
    int res = Gauss();
    for(int i = 0; i < n; i++)
    
        if(i)
            printf(" ");
        printf("%d", x[i]);
    
    printf("\n");


int main()

    int T;
    // freopen("input.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    scanf("%d", &T);
    while(T--)
    
        scanf("%d %s", &p, s);
        n = strlen(s);
        memset(a, 0, sizeof(a));
        for(int i = 0; i < n; i++)
        
            int res = 1;
            for(int j = 0; j < n; j++)
            
                a[i][j] = res;
                res = res * (i + 1) % p;
            
            a[i][n] = getInt(s[i]);
        
        solve();
    
    return 0;

  

以上是关于POJ_2065 SETI 同余高斯消元的主要内容,如果未能解决你的问题,请参考以下文章

POJ-2065-SETI(高斯消元)

POJ2065 SETI(高斯消元 同模方程)

POJ.2065.SETI(高斯消元 模线性方程组)

POJ SETI 高斯消元 + 费马小定理

POJ 2947-Widget Factory(高斯消元解同余方程式)

poj 2947 Widget Factory (高斯消元解同余方程组+判断无解多解)