题目链接:https://vjudge.net/problem/POJ-2065

题意:题目看着较复杂,实际上就是给了n个同余方程,解n个未知数。

思路:套高斯消元法的模板即可。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std; const int maxn=;
int T,equ,var,MOD,a[maxn][maxn],x[maxn];
char s[]; 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;
} void init(){
memset(x,,sizeof(x));
for(int i=;i<equ;++i){
int k=i+,t=;
for(int j=;j<var;++j){
a[i][j]=t;
t=t*k%MOD;
}
}
} int Gauss(){
int k=,LCM,ta,tb,tmp;
for(int col=;k<equ&&col<var;++k,++col){
int max_r=k;
for(int i=k+;i<equ;++i){
if(abs(a[i][col])>abs(a[max_r][col]))
max_r=i;
}
if(max_r!=k){
for(int i=col;i<var+;++i)
swap(a[max_r][i],a[k][i]);
}
if(!a[k][col]){
--k;
continue;
}
for(int i=k+;i<equ;++i){
if(!a[i][col]) continue;
LCM=lcm(a[i][col],a[k][col]);
ta=LCM/a[i][col];
tb=LCM/a[k][col];
if(a[i][col]*a[k][col]<) tb=-tb;
for(int j=col;j<var+;++j){
a[i][j]=((a[i][j]*ta-a[k][j]*tb)%MOD+MOD)%MOD;
}
}
}
for(int i=k;i<equ;++i){
if(a[i][var])
return -;
}
if(k<var){
return var-k;
}
for(int i=equ-;i>=;--i){
tmp=a[i][var];
for(int j=i+;j<var;++j){
if(!a[i][j]) continue;
tmp-=a[i][j]*x[j];
tmp=(tmp%MOD+MOD)%MOD;
}
while(tmp%a[i][i]!=) tmp+=MOD;
x[i]=(tmp/a[i][i])%MOD;
}
return ;
} int main(){
scanf("%d",&T);
while(T--){
scanf("%d%s",&MOD,s);
equ=var=strlen(s);
init();
for(int i=;i<equ;++i){
int t;
if(s[i]=='*') t=;
else t=s[i]-'a'+;
a[i][var]=t;
}
Gauss();
for(int i=;i<var;++i){
printf("%d",x[i]);
if(i!=var-) printf(" ");
}
printf("\n");
}
return ;
}
05-12 13:41