POJ 2065 SETI

POJ_2065

    题目既然没有说无解的情况就当做一定有解来看待了,根据题意可以列出n个同余方程,然后用高斯消元+拓展欧几里得求得每个ai就可以了。

#include<stdio.h>

#include<string.h>

#include<iostream>

#define MAXD 80

using namespace std;

int mat[MAXD][MAXD], N, P, ans[MAXD];

char b[MAXD], ch[128];

void prepare()

{

    int i;

    for(i = 'a'; i <= 'z'; i ++)

        ch[i] = i - 'a' + 1;

    ch['*'] = 0;

}

void exgcd(int a, int b, int &x, int &y)

{

    if(b == 0)

        x = 1, y = 0;

    else

        exgcd(b, a % b, y, x), y -= x * (a / b);

}

int powmod(int a, int n)

{

    int ans = 1, t = a;

    while(n)

    {

        if(n & 1)

            ans = (ans * t) % P;

        n >>= 1;

        t = (t * t) % P;

    }

    return ans;

}

void init()

{

    int i, j, k;

    scanf("%d", &P);

    scanf("%s", b);

    N = strlen(b);

    for(i = 0; i < N; i ++)

    {

        mat[i][N] = ch[b[i]];

        for(j = 0; j < N; j ++)

            mat[i][j] = powmod(i + 1, j);

    }

}

void gauss()

{

    int i, j, k, a, b, x, y;

    for(i = 0; i < N; i ++)

    {

        if(mat[i][i] == 0)

        {

            for(j = i + 1; j < N; j ++)

                if(mat[j][i])

                {

                    for(k = i; k <= N; k ++)

                        swap(mat[i][k], mat[j][k]);

                    break;

                }

        }

        a = mat[i][i];

        for(j = i + 1; j < N; j ++)

            if(mat[j][i])

            {

                b = mat[j][i];

                for(k = i; k <= N; k ++)

                    mat[j][k] = (mat[j][k] * a - mat[i][k] * b) % P;

            }

    }

    for(i = N - 1; i >= 0; i --)

    {

        a = (mat[i][i] + P) % P, b = mat[i][N];

        for(j = i + 1; j < N; j ++)

            b = (b - mat[i][j] * ans[j]) % P;

        b = (b + P) % P;

        exgcd(a, P, x, y);

        ans[i] = (((x % P) * b) % P + P) % P;

    }

}

void solve()

{

    int i;

    gauss();

    printf("%d", ans[0]);

    for(i = 1; i < N; i ++)

        printf(" %d", ans[i]);

    printf("\n");

}

int main()

{

    int t;

    prepare();

    scanf("%d", &t);

    while(t --)

    {

        init();

        solve();

    }

    return 0;

}

你可能感兴趣的:(set)