您的位置:首页 > 其它

poj 2065 SETI(数学:高斯消元)

2014-11-21 16:50 381 查看
题意不好理解,理解题意了就是一个模板题

构造矩阵:

x0*1^0+x1*1^1+...+xn*1^n-1 = (str[0])

x0*2^0+x1*2^1+...+xn*2^n-1 = (str[1])

……

x0*n^0+x1*n^1+...+xn*n^n-1 = (str[n-1])

但是因为涉及到取模。。。

模板还须加强啊

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 100
#define LL long long
using namespace std;

int x[MAXN];
char str[MAXN];
int a[MAXN][MAXN];
int free_x[MAXN];

void print(int n, int MOD) {
for(int i=0; i<n; ++i) {
for(int j=0; j<=n; ++j) {
printf("%d ", (a[i][j]+MOD)%MOD);
}
puts("");
}
}

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

int gauss(int n, int MOD) {
int ta, tb, LCM, col;
int free_x_num, free_index;
int i, j, k, max_r, tmp;

for(int i=0; i<=n; ++i) {
x[i] = 0;
free_x[i] = true;
}

col = 0;
for(k=0; k<n&&col<n; ++k, ++col) {
max_r = k;
for(i=k+1; i<n; ++i) {
if(abs(a[i][col]>abs(a[max_r][col])))
max_r = i;
}
if(max_r != k)
for(j=k; j<=n; ++j)
swap(a[k][j], a[max_r][j]);
if(a[k][col] == 0) {
--k;
continue;
}
for(i=k+1; i<n; ++i) {
if(a[i][col] != 0) {
LCM = lcm(abs(a[i][col]), abs(a[k][col]));
ta = LCM/abs(a[i][col]);
tb = LCM/abs(a[k][col]);
if(a[i][col]*a[k][col] < 0)
tb = -tb;
for(j=col; j<=n; ++j)
a[i][j] = ((a[i][j]*ta-a[k][j]*tb)%MOD+MOD)%MOD;
}
}
}
for(i=k; i<n; ++i)
if(a[i][col]) return -1;
if(k < n) {
for(i=k-1; i>=0; --i) {
free_x_num = 0;
for(j=0; j<n; ++j) {
if(a[i][j]!=0 && free_x[j])
free_x_num++, free_index = j;
}
if(free_x_num > 1) continue;
tmp = a[i]
;
for(j=0; j<n; ++j) {
if(a[i][j] && j!=free_index)
tmp -= a[i][j]*x[j]%MOD;
tmp = (tmp%MOD+MOD)%MOD;
}
while(tmp%a[i][free_index] != 0) tmp+=MOD;
x[free_index] = tmp/a[i][free_index]%MOD;
free_x[free_index] = 0;
}
return n-k;
}

for(i=n-1; i>=0; --i) {
int tmp = a[i]
;
for(j=i+1; j<n; ++j) {
if(a[i][j])
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;
}
//print(n, MOD);
return 0;
}

int pow_mod(int a, int b, int MOD) {
int ans = 1;
while(b) {
if(b & 1) {
ans = (ans*a)%MOD;
}
a = (a*a)%MOD;
b >>= 1;
}
return ans;
}

int main(void) {
int T, p;
scanf("%d", &T);
while(T--) {
scanf("%d", &p);
scanf("%s", str);
int n = strlen(str);
for(int i=0; i<n; ++i) {
if(str[i] == '*')
a[i]
= 0;
else a[i]
= str[i]-'a'+1;

for(int j=0; j<n; ++j) {
a[i][j] = pow_mod(i+1, j, p);
}
}

//print(n, p);
gauss(n, p);
printf("%d", x[0]);
for(int i=1; i<n; ++i)
printf(" %d", x[i]);
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: