首先a…z=1..26,*=0
读入p(模数且为质数),s(下标从0开始),s长度为n
求方程组
https://blog.csdn.net/Clove_unique/article/details/54381675
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=100;
int mod,a[maxn][maxn],x[maxn];
bool free_x[maxn];//标记是否是不确定的变元
int var,equ;
char str[maxn];
int p;
void ex_gcd(int a, int b, int &d, int &x, int &y) { if (!b) { x = 1; y = 0; d = a; } else { ex_gcd(b, a%b, d, y, x); y -= x * (a / b); }; }
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 inv_exgcd(int a, int m) { int d, x, y;ex_gcd(a, m, d, x, y);return d == 1 ? (x + m) % m : -1; }
void init()
{
memset(a, 0, sizeof(a));
var=equ=strlen(str);
for(int i=0;i<equ;++i)
{
int te=1;
for(int j=0;j<var;++j)
{
a[i][j]=te;//做的第一道题关于高斯消元的板子,博主能想到这种构造出k^i的数值也是很服气
te=te*(i+1)%p;
}
a[i][var]=(str[i]=='*')?0:int(str[i]-'a'+1);//常量 题目中说的f(k)
}
}
int Gauss()
{
int i,j,k;
int max_r;// 当前这列绝对值最大的行.
int col;//当前处理的列
int ta,tb;
int LCM;
int temp;
for(col=0,k = 0;k < equ && col < var;++k,++col)
{
max_r=k;
for(i=k+1;i<equ;i++)
{
if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
}
if(max_r!=k)
{
for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]);
}
if(a[k][col]==0)
{
k--;continue;
}
for(i=k+1;i<equ;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<var+1;j++)
{
a[i][j] =((a[i][j]*ta-a[k][j]*tb)%p+p)%p;;
}
}
}
}
for (i = k; i < equ; i++)
{
if (a[i][col] != 0) return -1;
}
for (i = var - 1; i >= 0; i--)//对应的就是从单位矩阵中为1的位置去解,跟着这个循环走两边就知道是怎么接出来唯一解的了
{
temp = a[i][var];
for (j = i + 1; j < var; j++)
{
if (a[i][j] != 0) temp =((temp- a[i][j] * x[j])%p+p)%p;//
}
int g=inv_exgcd(a[i][i],p);
x[i]=temp*g%p;
}
return 0;
}
int main()
{
int i, j;
int t;
cin>>t;
while(t--)
{
scanf("%d %s",&p,str);
init();
Gauss();
cout<<x[0];
for (i = 1; i < var; i++)
printf(" %d",x[i]);
printf("\n");
}
return 0;
}