The question is quite tangled and I searched for the question.
Returns a prime number P (P <= 30000) and a string str [] with a length of n. The letter '*' represents 0, and the letter a-z represents 1-26, respectively. The n characters represent numbers respectively.
F (1), f (2)... f (n ). Definition: f (k) = Σ 0 <= I <= n-1aiki (mod p) (1 <= k <= n, 0 <= ai <P ), a0, a1 ..... an-1. The question guarantee must have a unique solution.
Solution: Gaussian elimination. According to the above formula, we can clearly list the n equations with n unknowns:
A0 * 1 ^ 0 + a1 * 1 ^ 1 + a2 * 1 ^ 2 + ........ + an-1*1 ^ (n-1) = f (1)
A0 * 2 ^ 0 + a1 * 2 ^ 1 + a2 * 2 ^ 2 + ........ + an-1*2 ^ (n-1) = f (2)
..............
A0 * n ^ 0 + a1 * n ^ 1 + a2 * n ^ 2 + ........ + an-1 * n ^ (n-1) = f (n)
Then, use Gaussian elimination method to solve the above equations.
The typical Gaussian elimination problem only has a modP, so the Euclidean algorithm may need to be extended in the calculation process.
For more information about the concept of Gaussian elimination, see Wikipedia,
Bytes.
For example, at the beginning, the first variable is eliminated. After the elimination, only the first equation contains the first variable, and then the second variable is eliminated, after elimination, let the second equation contain the second variable.
Let the last equation contain the last variable, and the coefficient of the first N-1 variable in the last equation is 0, so that the N variables can be solved.
Free meta indicates that this variable can take any value, the conclusion is that the coefficient of the variable from the row equation to the N equation is 0,
Therefore, you can obtain any value. The way to judge the unsolvable is that all the coefficients of the row + 1 to the N equation after Gaussian elimination must be 0, so the value of the equation must be 0.
The process of solving the equation is from the N solution start to backward push, the N-1 equation also contains 2 variables, the N variables and the N-1 variables, in order to continue, you can solve the equations.
For more information, see Wikipedia and code. There is also an explanation of Gaussian deyuan in the algorithm notes.
The Code is as follows:
# Include <stdio. h>
# Include <string. h>
# Include <algorithm>
Using namespace std;
# Define MAX (70 + 10)
Int nMatrix [MAX] [MAX];
Int nAns [MAX];
Void InitMatrix (char * szStr, int nN, int nP)
{
Memset (nMatrix, 0, sizeof (nMatrix ));
For (int I = 0; I <nN; ++ I)
{
NMatrix [I] [nN] = (szStr [I] = '*'? 0: szStr [I]-'A' + 1 );
}
For (int I = 0; I <nN; ++ I)
{
Int nTemp = 1;
For (int j = 0; j <nN; ++ j)
{
NMatrix [I] [j] = nTemp;
NTemp = (nTemp * (I + 1) % nP;
}
}
}
Int egcd (int nA, int nB, int & nX, int & nY)
{
If (nA <nB) swap (nA, nB );
If (nB = 0)
{
NX = 1, nY = 0;
Return nA;
}
Int nRet = egcd (nB, nA % nB, nX, nY );
Int nT = nX;
NX = nY;
NY = nT-(nA/nB) * nY;
Return nRet;
}
Int Gauss (int nN, int nP)
{
Int nR, nC;
For (nR = nC = 0; nR <nN & nC <nN; ++ nR, ++ nC)
{
If (nMatrix [nR] [nC] = 0)
{
For (int I = nR + 1; I <nN; ++ I)
{
If (nMatrix [I] [nC])
{
For (int j = nC; j <= nN; ++ j)
{
Swap (nMatrix [nR] [j], nMatrix [I] [j]);
}
Break;
}
}
}
If (nMatrix [nR] [nC] = 0)
{
NR --; // free RMB
Continue;
}
Int nA = nMatrix [nR] [nC];
For (int I = nR + 1; I <nN; ++ I)
{
If (nMatrix [I] [nC])
{
Int nB = nMatrix [I] [nC];
For (int j = nC; j <= nN; ++ j)
{
NMatrix [I] [j] = (nMatrix [I] [j] * nA-nMatrix [nR] [j] * nB) % nP;
}
}
}
}
For (int I = nR; I <nN; ++ I)
{
If (nMatrix [I] [nN])
{
Return-1; // no solution
}
}
Int nX, nY;
For (int I = nN-1; I> = 0; I --)
{
Int nSum = 0;
For (int j = I + 1; j <nN; ++ j)
{
NSum = (nSum + nMatrix [I] [j] * nAns [j]) % nP;
}
NSum = (nMatrix [I] [nN]-nSum + nP * nP) % nP;
Egcd (nP, (nMatrix [I] [I] + nP) % nP, nX, nY );
NY = (nY + nP) % nP;
NAns [I] = (nY * nSum + nP) % nP; // the I-th Solution
}
Return 1 <(nN-nR); // return the number of solutions. This question has a unique solution.
}
Int main ()
{
Int nT;
Scanf ("% d", & nT );
While (nT --)
{
Int nP;
Int nN;
Char szStr [MAX];
Scanf ("% d % s", & nP, szStr );
NN = strlen (szStr );
InitMatrix (szStr, nN, nP );
Gauss (nN, nP );
For (int I = 0; I <nN; ++ I)
{
Printf ("% d % s", nAns [I], I = nN-1? "\ N ":"");
}
}
Return 0;
}