hdu 1211 二种解法 求逆元 水题

hdu 1211 2种解法 求逆元 水题

RSA

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 853    Accepted Submission(s): 632


Problem Description
RSA is one of the most powerful methods to encrypt data. The RSA algorithm is described as follow:

> choose two large prime integer p, q
> calculate n = p × q, calculate F(n) = (p - 1) × (q - 1)
> choose an integer e(1 < e < F(n)), making gcd(e, F(n)) = 1, e will be the public key
> calculate d, making d × e mod F(n) = 1 mod F(n), and d will be the private key

You can encrypt data with this method :

C = E(m) = me mod n

When you want to decrypt data, use this method :

M = D(c) = cd mod n

Here, c is an integer ASCII value of a letter of cryptograph and m is an integer ASCII value of a letter of plain text.

Now given p, q, e and some cryptograph, your task is to "translate" the cryptograph into plain text.
 

Input
Each case will begin with four integers p, q, e, l followed by a line of cryptograph. The integers p, q, e, l will be in the range of 32-bit integer. The cryptograph consists of l integers separated by blanks.
 

Output
For each case, output the plain text in a single line. You may assume that the correct result of plain text are visual ASCII letters, you should output them as visualable letters with no blank between them.
 

Sample Input
101 103 7 11 7716 7746 7497 126 8486 4708 7746 623 7298 7357 3239
 

Sample Output
I-LOVE-ACM.
 

Author
JGShining(极光炫影)
 

Source
杭电ACM省赛集训队选拔赛之热身赛
 

Recommend
Eddy


本题难点在于 难于理解题意 hdu 1211   二种解法  求逆元   水题

题意:

输入数字 进行解码

解码方式  M = D(c) = cd mod n 对于输入的数c能够解码到M   M即使我们要的明文  按字符型输出  

另外 C = E(m) = me mod n 是加密方式 不用管它

输入p, q, e, l   那么可以得到n = p × q,  F(n) = (p - 1) × (q - 1)

 那么n知道 c是输入的  只要求出d就可以了

题设条件为d × e mod F(n) = 1 mod F(n),
即(d*e)%fn==1%fn

那么我可以很容易的根据这个式子 求出来d    第一种方法 直接暴力 第二种方法就是扩展欧几里得  

欧科  贴代码

#include<stdio.h>
#include<math.h>
int main()
{
	int p,q,e,n,d,m,c,fn,i,j,t;
	while(scanf("%d %d %d %d",&p,&q,&e,&t)!=EOF)
    {
            n=p*q;
			fn=(p-1)*(q-1);
			d=fn/e+1;
			while((d*e)%fn!=1) d++;
			for(i=0;i<t;i++)
			{
				scanf("%d",&c);
				m=1;
				for(j=0;j<d;j++)
				{
					m*=c;
					m%=n;
				}
				printf("%c",m);
			}
			printf("\n");
	}
	return 0;
}

#include<stdio.h>
#include<math.h>
int x,y;
int GCD(int a,int b)
{
	__int64 t,d;
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	d=GCD(b,a%b);
	t=x;
	x=y;
	y=t-(a/b)*(y); 
    return d;
}
int main()
{
	int p,q,e,n,d,m,c,fn,i,j,t,gcd,k;
	while(scanf("%d %d %d %d",&p,&q,&e,&t)!=EOF)
    {
		n=p*q;
		fn=(p-1)*(q-1);
		gcd=GCD(e,fn);//a,b
		d=x*(1/gcd);//d就是模板中的x0
        k=d/(fn/gcd);
		d=d-k*(fn/gcd);
		if(d<0) d=d+fn/gcd;
		for(i=0;i<t;i++)
		{
			scanf("%d",&c);
			m=1;
			for(j=0;j<d;j++)
			{
				m*=c;
				m%=n;
			}
			printf("%c",m);
		}
		printf("\n");
	}
	return 0;
}