题目链接: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=75; int T,equ,var,MOD,a[maxn][maxn],x[maxn]; char s[75]; 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,0,sizeof(x)); for(int i=0;i<equ;++i){ int k=i+1,t=1; for(int j=0;j<var;++j){ a[i][j]=t; t=t*k%MOD; } } } int Gauss(){ int k=0,LCM,ta,tb,tmp; for(int col=0;k<equ&&col<var;++k,++col){ int max_r=k; for(int i=k+1;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+1;++i) swap(a[max_r][i],a[k][i]); } if(!a[k][col]){ --k; continue; } for(int i=k+1;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]<0) tb=-tb; for(int j=col;j<var+1;++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 -1; } if(k<var){ return var-k; } for(int i=equ-1;i>=0;--i){ tmp=a[i][var]; for(int j=i+1;j<var;++j){ if(!a[i][j]) continue; 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; } return 0; } int main(){ scanf("%d",&T); while(T--){ scanf("%d%s",&MOD,s); equ=var=strlen(s); init(); for(int i=0;i<equ;++i){ int t; if(s[i]=='*') t=0; else t=s[i]-'a'+1; a[i][var]=t; } Gauss(); for(int i=0;i<var;++i){ printf("%d",x[i]); if(i!=var-1) printf(" "); } printf(" "); } return 0; }