http://poj.org/problem?id=2065
思路:http://blog.youkuaiyun.com/winddreams/article/details/47260465
/*
解模线性方程
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100;
int a[maxn][maxn];
int x[maxn],free_x[maxn];
void print(int n)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<=n;j++)
printf("%d ",a[i][j]);
printf("\n");
}
printf("\n");
}
int lcm(int a,int b)
{
return (a/__gcd(a,b))*b;
}
int Pow(int a,int n,int MOD)
{
int ans=1;
int res=a%MOD;//
while(n)
{
if(n&1)ans=(ans*res)%MOD;
res=(res*res)%MOD;
n>>=1;
}
return ans;
}
int Gauss(int equ,int var,int MOD)
{
int maxrow;
int row=0,col=0,num=0;
for(;row<equ&&col<var;row++,col++)//
{
maxrow=row;
for(int k=row+1;k<equ;k++)
if(abs(a[k][col])>abs(a[maxrow][col]))maxrow=k;
if(maxrow!=row)
{
for(int j=row;j<=var;j++)//
swap(a[maxrow][j],a[row][j]);
}
if(a[row][col]==0)
{
row--;
continue;
}
for(int i=row+1;i<equ;i++)
{
if(a[i][col]!=0)
{
int LCM=lcm(a[row][col],a[i][col]);
int tb=LCM/a[row][col];
int ta=LCM/a[i][col];
if(a[row][col]>0&&a[i][col]<0||a[row][col]<0&&a[i][col]>0)tb=-tb;
for(int j=0;j<=var;j++)
a[i][j]=((a[i][j]*ta-a[row][j]*tb)%MOD+MOD)%MOD;
}
}
}
//保证有解 printf("ssss\n");
for(int i=var-1;i>=0;i--)
{
int temp=a[i][var];
for(int j=i+1;j<var;j++)
{
if(a[i][j]!=0)temp= temp-a[i][j]*x[j];
temp=(temp%MOD+MOD)%MOD;//
}
while(temp%a[i][i]!=0)temp+=MOD;
x[i]=(temp/a[i][i])%MOD;
}
return 0;
}
int main()
{
int t;
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
scanf("%d",&t);
while(t--)
{
int MOD;
scanf("%d",&MOD);
char s[100];
scanf("%s",s);
int n=strlen(s);
memset(a,0,sizeof(a));
for(int i=0;i<n;i++)
{
if(s[i]=='*')a[i][n]=0;
else a[i][n]=s[i]-'a'+1;
for(int j=0;j<n;j++)
a[i][j]=Pow(i+1,j,MOD);
}
// print(n);
Gauss(n,n,MOD);
for(int i=0;i<n;i++)
if(i!=n-1)printf("%d ",x[i]);
else printf("%d\n",x[i]);
}
}

本文提供了一种解决模线性方程组的方法,并通过一个具体的C++程序实现了高斯消元法求解该类方程组的过程。适用于求解形如ax ≡ b (mod m)的方程,其中涉及了最小公倍数、幂运算及高斯消元等算法。
682

被折叠的 条评论
为什么被折叠?



