题目:hdu 2466 Cryptography Reloaded
思路:这题就是给出RSA加密的公钥和私钥求初始的两个质数。
开始的时候被几个同余方程给迷惑了,不知从何下手。
然后看了这里的 解题报告 。
然后联立方程组得到:
(p-1)*(q-1)=t p*q=n
delta=sqrt((t-n-1)^2-4*n)
p=(n+1-t+sqrt(delta))/2;
q=(n+1-t-sqrt(delta))/2;
一直找到满足这样的式子能够整除能够开方的值(竟然不需要判素数)输出就行
import java.math.BigInteger;
import java.util.*;
public class Main{
public static BigInteger sqrt(BigInteger n)
{
BigInteger l=BigInteger.ZERO,r=n,mid,tmp;
while(l.compareTo(r)<0)
{
mid=(l.add(r)).divide(BigInteger.valueOf(2));
tmp=mid.multiply(mid);
if(tmp.compareTo(n)>0)
r=mid.subtract(BigInteger.ONE);
else if(tmp.compareTo(n)<0)
l=mid.add(BigInteger.ONE);
else
return mid;
}
return l;
}
public static boolean can_sqrt(BigInteger n) {
BigInteger tmp=sqrt(n);
tmp=tmp.multiply(tmp);
if(tmp.compareTo(n)==0)
return true;
return false;
}
public static void main(String args[])
{
int cas=0;
Scanner cin=new Scanner(System.in);
BigInteger n,d,e;
while(cin.hasNext())
{
n=cin.nextBigInteger();
d=cin.nextBigInteger();
e=cin.nextBigInteger();
if(n.compareTo(BigInteger.ZERO)==0 && e.compareTo(BigInteger.ZERO)==0 && d.compareTo(BigInteger.ZERO)==0)
{
break;
}
d=d.multiply(e);
d=d.subtract(BigInteger.ONE);
int i=0;
while(true)
{
i++;
// pq = n
// de-1 = k*(p-1)*(q-1) 枚举(p-1)(q-1)=tmp
BigInteger tmp=d.mod(BigInteger.valueOf(i));
if(tmp.compareTo(BigInteger.ZERO)>0)
continue;
tmp=d.divide(BigInteger.valueOf(i));
BigInteger delta=((n.subtract(tmp.add(BigInteger.ONE))).pow(2)).subtract(tmp.multiply(BigInteger.valueOf(4)));
if(can_sqrt(delta)==true)
{
delta=sqrt(delta);
BigInteger p,q;
p=((n.subtract(tmp.subtract(BigInteger.ONE))).subtract(delta)).divide(BigInteger.valueOf(2));
q=((n.subtract(tmp.subtract(BigInteger.ONE))).add(delta)).divide(BigInteger.valueOf(2));
if(p.compareTo(q)>0)
{
BigInteger cnt=p;
p=q;
q=cnt;
}
System.out.println("Case #"+ ++cas +": "+p+" "+q);
break;
}
}
}
}
}