Decrypt |
Time limit : 1000ms, Special time limit:2500ms, Memory Limit: 65536KB |
Total Submit Users: 2, Accepted users: 0 |
problem 11552: No Special Judgement |
Problem description |
cryptography, there is a method of encryption, called Hill encryption method. The encryption steps are as follows: Step1: String to be encrypted s={s[0], s[1], ...} (for simplicity, in the case, the string s contains only lowercase letters) press s[n-1, a->0 >2, ..., y->24, z->25 rules converted to an array of shapes a={a[0], a[1], ..., a[n-1]}; Step2: Divides the array A into k parts of equal length, each part length is L (guaranteed to k*l=s the length of the string s to be encrypted) SETP3: Add each part to the left by one L * L matrix A, the result vector all the values to 26 modulo replace the original part, to obtain a new array B={b[0], b[1], ..., b[n-1]}, is the element in B that satisfies: (B[i * k],b[i * k + 1], ..., b[i * k + (L-1)]) = (A[i * k],a[i * k + 1], ..., a[i * k + (L-1)]) *a Step4: Press the number in array B to 0->a, 1->b, 2->c, ..., 24->y, 25->z, convert the rules to ciphertext For example: Encryption July, Matrix A=[11 8;3 7] (semicolon denotes another line) Step1: Convert July to an array a={9, one, one, and one}; STEP2: Divide a into {9, 20},{11, 24} two parts Step3: Because [9,] * [one 8;3 7] = [159, 212] [11, 24] * [11 8;3 7]=[19 3, []] b=[159%, 212%, 193%, [3, 4, one,] Step4: Ciphertext is DELW Your task is: give you ciphertext and matrix A, the original string &NB SP; |
Input |
The first behavior is an integer T (0 < T < 20), which represents the number of groups of data. The first behavior of each set of data is an encrypted string consisting of a lowercase letter with a length of not more than 10000. The second behavior is an integer m (0 < M <= 100 and the length of the string can be divisible by m), indicating that matrix A is a matrix of m*m followed by M-line, M-integer per line, representing matrix A, input data guaranteed matrix A main diagonal element and 26-factor
|
Output |
For each set of data, the output line is the original text corresponding to the ciphertext
|
Sample Input |
2 Delw 2 11 8 3 7 Pabqlzqii 3 1 14 2 5 9 2 4 7 3 |
Sample Output |
July qvtusjkcm |
Problem Source |
Hunnu Contest |
Hill decryption; Need to find the inverse matrix first;
I can only go through the first group .... Great gods, please explain ...
#include <math.h> #include <string.h> #include <malloc.h> #include <iostream> #include < Iomanip> #include <stdio.h>using namespace std; #define N 105//define the maximum order of the Phalanx as the declaration part of the 10//function double Matdet ( Double *p, int n); To find the determinant of a matrix double creat_m (double *p, int M, int n, int k); Computes the algebraic my-type void print (double *p, int n) of the matrix element A (m, n); Output matrix N*nbool Gauss (double a[][n], double b[][n], int N); The inverse matrix of a square matrix bdouble a[n][n],b[n][n];int C[n][n];d ouble determ is obtained by using the Gaussian elimination method of partial principal element; Define the determinant of the matrix//int zimu[26];int gcd (int a,int b) {if (!b) return A; GCD (b,a%b);} void Print (int mm[],int k) {/* for (int i=0; i<k; i++) {printf ("%d", mm[i]); } printf ("\ n"); */for (int i=0; i<k; i++) {for (int j=0; j<k; J + +) {printf ("%d", C I [j]); } printf ("\ n"); }//Double tp[105]= {0}; int tp[105]={0}; for (int i=0; i<k; i++)//column {for (int j=0; j<k; J + +)//Line | | MM line {tp[i]+=mm[j]*c[j][i];//printf ("tp=%d\tmm=%d\tb=%d\n", Tp[i],mm[j],c[j][i]); }} for (int i=0; i<k; i++) {//int tmp= (int) (tp[i]);//printf ("%d\t", TMP); printf ("%c", ((Tp[i])%26+26)%26+ ' a '); while (tp[i]<0) tp[i]+=26; printf ("%c\n", (int) (tp[i])%26+ ' a '); }//printf ("\ n");} int main () {//Freopen ("Xier.txt", "R", stdin); Double *buffer, *p; Define array first address pointer variable int row, num; Defines the number of rows and matrix elements of a matrix//int i, J; int n;//for (int i=0;i<26;i++)//zimu[i]=i; int t,len,m,mo[105]; Char mi[10005]; scanf ("%d", &t); while (t--) {scanf ("%s", MI); Len=strlen (MI); scanf ("%d", &n); Row=n; num = 2*row*row; Buffer = (double *) calloc (num, sizeof (double)); Allocate memory unit p = buffer; for (int i=0, i<n; i++) {for (int j=0; j<n; J + +) {scanf ("%lf", &a[i][j]); *P++=A[I][J]; }} determ = Matdet (buffer, row); Find the determinant of the whole matrix//printf ("determ=%lf\n", determ); int D=GCD ((int) (determ), 27); d= (int) determ*27/d; printf ("***************************************d=%d\n", D); for (int i = 0; i < row; i++)//Inverse matrix {for (int j = 0; J < Row; J + +) { * (p+j*row+i) = creat_m (buffer, I, J, Row) *d/determ; }} print (P, row); Free (buffer); Free memory space for (int i=0; i<len; i++) {//printf ("mi=%c\n", Mi[i]); mo[i%n]=mi[i]-' a '; printf ("i=%d\tmo=%d\n", i%n,mo[i%n]); if ((i+1)%n==0) Print (mo,n); } printf ("\ n"); for (int i=0, i<n; i++)//{//for (int j=0; j<n; j + +)//{//Print F ("%lf", A[i][j]); // } // printf ("\ n"); }//if (Gauss (a,b,n))//{/* for (int i = 0; i < n; i++) { cout << SETW (4); for (int j = 0; J < N; j + +) {cout << b[i][j] << setw (10); } cout << Endl; }*///}} return 0;} -----------------------------------------------//function: Matrix (n*n) determinant//Entry parameter: The first address of the matrix, the number of rows//Return values: The determinant value of the matrix//---------- ------------------------------------double Matdet (double *p, int n) {int r, C, M; int lop = 0; Double result = 0; Double mid = 1; if (n! = 1) {lop = (n = = 2)? 1:n; Control sum cycle, if 2 order, then loop 1 times, otherwise n for (m = 0; m < lop; m++) {mid = 1; Order sum, the sum of the main diagonal elements multiplied by for (R = 0, C = m; r < N; r++, C + +) {mid = Mid * (* (p+r*n+c%n) ); } result + = Mid; } for (m = 0; M < Lop; m++) {mid = 1; Subtract in reverse order, minus the second diagonal element product for (r = 0, c = n-1-m+n; r < N; r++, c--) {mid = Mid * (* (p+r* n+c%n)); } result-= mid; }} else result = *p; return result;} ----------------------------------------------------------------------------//function: To find the algebraic my of element a (M, n) in K*k matrix//Inlet parameter : The first address of the k*k matrix, the subscript m,n of the matrix element A, the number of rows k//The return value: Algebraic my of element a (M, N) in the k*k matrix//------------------------------------------------------ ----------------------Double creat_m (double *p, int M, int n, int k) {int len; int I, J; Double Mid_result = 0; int sign = 1; Double *p_creat, *p_mid; Len = (k-1) * (k-1); The algebraic my of the K-order matrix is the k-1-order Matrix P_creat = (double*) calloc (len, sizeof (double)); Allocate memory Unit p_mid = p_creat; for (i = 0, i < K; i++) {for (j = 0; J < K; J + +) {if (i! = m && J! = N)//will be in addition to section I All elements outside the row and column J are stored to the memory unit with the P_mid-first address { *p_mid++ = * (P+I*K+J); }}} sign = (m+n)%2 = = 0? 1:-1; Algebraic my front positive, minus sign Mid_result = (double) Sign*matdet (P_creat, k-1); Free (p_creat); return mid_result;} -----------------------------------------------------//function: Print n*n matrix//Ingress parameters: N*n Matrix's first address, number of rows in the matrix n//return value: No return value//-------- ---------------------------------------------void print (double *p, int n) {int i, J; for (i = 0; i < n; i++) {//cout << SETW (4); for (j = 0; J < N; j + +) {c[i][j]= (int) *p++; while (c[i][j]<0) c[i][j]+=26; cout << setiosflags (ios::right) << *p++ << SETW (10); }//cout << Endl; }}//------------------------------------------------------------------//function: Using the Gaussian elimination method of partial principal element to find the inverse matrix of square a b//inlet parameter: input phalanx, Output Phalanx, matrix order//return value: TRUE or false//-------------------------------------------------------------------bool Gauss ( Double A[][n], double b[][n], int N) {int I, j, K; Double Max, temp;Double T[n][n]; Temporary matrix//The A matrix is stored in the temporary matrix T[n][n] for (i = 0; i < n; i++) {for (j = 0; J < N; j + +) {T I [j] = a[i][j]; }}//Initialize B matrix for unit array for (i = 0; i < n; i++) {for (j = 0; J < N; j + +) {B[i][j] = (i = = j)? (double) 1:0; }} for (i = 0; i < n; i++) {//find main element max = T[i][i]; K = i; for (j = i+1; J < N; j + +) {if (Fabs (T[j][i]) > Fabs (max)) {max = t[j][ I]; K = J; }}//If the main element row is not the first row, do the line exchange if (k! = i) {for (j = 0; J < N; j + +) { temp = T[i][j]; T[I][J] = T[k][j]; T[K][J] = temp; B accompanying Exchange temp = B[i][j]; B[I][J] = B[k][j]; B[K][J] = temp; }}//To determine if the principal is 0, if the matrix A is not a full rank matrix, there is no inverse matrix if (t[I][i] = = 0) {cout << "there is no inverse matrix!"; return false; }//Elimination of column I of a to remove rows other than line element temp = T[i][i]; for (j = 0; J < N; j + +) {T[i][j] = t[i][j]/temp; The elements on the main diagonal become 1 b[i][j] = b[i][j]/temp; Adjoint calculation} for (j = 0; J < N; j + +)//No. 0 row, nth row {if (j! = i)//not Line I {temp = t[j][i]; for (k = 0; k < n; k++)//J row Element-I row element *j column I row element {t[j][k] = t[j][k]-T[i][k]*te mp B[J][K] = b[j][k]-b[i][k]*temp; }}}} for (int i=0, i<n; i++) {for (int j=0; j<n; J + +) {B[i][j ]*=determ; }//printf ("\ n"); } return true;
Hill encryption Algorithm (sixth session of Hunan Normal University computer Program design Competition) hnuoj11552