POJ-2065-SETI(ガウスの消去)

リンク:

https://vjudge.net/problem/POJ-2065

質問の意味:

何年かのために、仕事のかなり多くは、遠方の銀河で文明が私たちに伝えようとする可能性があるかを理解するためには、宇宙から受信した電磁無線信号を聴いに置かれています。Universit'eデテクSpatialeの科学者に特に注目されている一つの信号源は、星雲Stupidicusです。
最近、それが発見された、各メッセージは、整数A0、A1、...、N-1関数f(k)の配列=Σ0 <= I <= N-1A IK I(として送信されると仮定されている場合MOD pは)常に値0と評価<= F(K)<= 26 1 <= K <= N、Pの正しい値が使用されることを条件とします。Nは、もちろん、送信されたメッセージの長さであり、そのようなAI 0 <= AI <Pその整数を表します。pはしかし、30 000を超えないことが知られているnよりも大きいだけでなく、26よりも大きいことが保証されている素数で
さらなる調査を求めており、これらの関係は完全に純粋な偶然の一致であることのためにあまりにも独特考えられてきました。
Languesらの文化Extraterrestresの教員の言語学者はその意味を解釈しようとしているときに処理するためのメッセージを容易にするために、英語のアルファベットの文字列にこれらのメッセージを転写します。転写手順は、単にアスタリスク(値0が「*」に転写されるような1 = A、2 = bのそのF(k)はに評価かもしれない値1..26、等にA..Z文字を割り当てます)。nは、K = 1からのメッセージを転写、言語学者は、単にループしながら、文字列の末尾にF(k)の値に対応する文字を追加します。
後方転写手順は、しかし、言語学者は、自分で処理するにはあまりにも複雑であることが判明しました。そのため、それらに対応するエクストラTerrestial数配列に文字列のセットを変換するプログラムを作成する作業を割り当てられています。

アイデア:

方程式が確立された、モジュロの場合には、分割処理は、逆であってもよいです。

コード:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<math.h>
#include<vector>

using namespace std;
typedef long long LL;
const int INF = 1e9;

const int MAXN = 100+10;

int equ, var, p;
int Mar[MAXN][MAXN];
int X[MAXN];
char s[MAXN];

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 PowMod(int a, int b, int c)
{
    int res = 1;
    while(b > 0)
    {
        if (b&1)
            res = res*a%c;
        a = a*a%c;
        b >>= 1;
    }
    return res;
}

int Inv(int a, int p)
{
    int inv = PowMod(a, p-2, p);
    return inv;
}

int Gauss()
{
    int row, col;
    row = col = 0;
    while(row < equ && col < var)
    {
        int max_r = row;//Max Line
        for (int i = row+1;i < equ;i++)
        {
            if (abs(Mar[i][col]) > abs(Mar[max_r][col]))
                max_r = i;
        }
        if (max_r != row)
        {
            for (int j = col;j < var+1;j++)
                swap(Mar[row][j], Mar[max_r][j]);
        }
        if (Mar[row][col] == 0)
        {
            col++;
            continue;
        }
        for (int i = row+1;i < equ;i++)
        {
            if (Mar[i][col] == 0)
                continue;
            int LCM = Lcm(Mar[row][col], Mar[i][col]);
            int ta = LCM/Mar[i][col];
            int tb = LCM/Mar[row][col];
            if (Mar[i][col]*Mar[row][col] < 0)
                tb = -tb;
            for (int j = col;j < var+1;j++)
                Mar[i][j] = ((Mar[i][j]*ta-Mar[row][j]*tb)%p+p)%p;
        }
        row++;
        col++;
    }
    for (int i = row;i < var;i++)
    {
        if (Mar[i][var] != 0)
            return -1;
    }
    if (row < var)
        return var-row;
    for (int i = var-1;i >= 0;i--)
    {
        int tmp = Mar[i][var];
        for (int j = i+1;j < var;j++)
            tmp = ((tmp-Mar[i][j]*X[j])%p+p)%p;
        X[i] = (tmp*Inv(Mar[i][i], p))%p;
    }
    return 0;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &p);
        scanf("%s", s);
        equ = var = strlen(s);
        for (int i = 0;i < equ;i++)
        {
            for (int j = 0;j < var;j++)
                Mar[i][j] = PowMod(i+1, j, p);
            if (s[i] == '*')
                Mar[i][var] = 0;
            else
                Mar[i][var] = s[i]-'a'+1;
        }
        Gauss();
        for (int i = 0;i < var-1;i++)
            printf("%d ", X[i]);
        printf("%d\n", X[var-1]);
    }

    return 0;
}

おすすめ

転載: www.cnblogs.com/YDDDD/p/11795814.html