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

浙公网安备 33010602011771号