poj 2065 SETI 高斯消元

时间:2023-03-10 02:07:15
poj 2065 SETI 高斯消元

看题就知道要使用高斯消元求解!

代码如下:

#include<iostream>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<cstring>
using namespace std;
int an[][],p,ans[];
char str[];
int pows(int a,int b)
{
int ans=;
while(b){
if(b&) ans=(ans*a)%p;
b>>=;
a=(a*a)%p;
}
return ans%p;
}
int gcd(int a,int b)
{
if(a<b) swap(a,b);
while(b){
int t=a;
a=b;
b=t%b;
}
return a;
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
void show(int n)
{
for(int i=;i<n;i++){
for(int j=;j<=n;j++)
cout<<an[i][j]<<' ';
cout<<endl;
}
cout<<endl;
}
void Gauss(int n)
{
int i,j,k,ma,mb,LCM;
for(i=;i<n;i++){
int row=i;
for(j=i+;j<n;j++)
if(an[j][i]>an[row][i]) row=j;
if(row!=i){
for(j=;j<=n;j++)
swap(an[i][j],an[row][j]);
}
for(j=i+;j<n;j++){
if(an[j][i]){
LCM=lcm(an[i][i],an[j][i]);
ma=LCM/an[i][i];
mb=LCM/an[j][i];
for(k=i;k<=n;k++){
an[j][k]=mb*an[j][k]-ma*an[i][k];
an[j][k]=(an[j][k]%p+p)%p;
}
}
}
}
for(i=n-;i>=;i--){
for(j=i+;j<n;j++){
an[i][n]-=ans[j]*an[i][j];
an[i][n]=an[i][n]%p;
}
while(an[i][n]%an[i][i]) an[i][n]+=p;
ans[i]=an[i][n]/an[i][i];
ans[i]=(ans[i]%p+p)%p;
}
}
int main()
{
int t,len,i,j,k;
cin>>t;
while(t--){
cin>>p>>str;
len=strlen(str);
for(i=;i<len;i++){
for(j=;j<len;j++){
an[i][j]=pows(i+,j);
}
if(str[i]=='*')
an[i][len]=;
else an[i][len]=str[i]-'a'+;
}
Gauss(len);
for(i=;i<len-;i++)
cout<<ans[i]<<' ';
cout<<ans[i]<<endl;
}
}