您的位置:首页 > 其它

poj2635 The Embarrassed Cryptographer(高精度 同余取模)

2016-08-20 20:17 387 查看
The Embarrassed Cryptographer

Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 13831Accepted: 3762
Description


The young and very promising cryptographer Odd Even has implemented the security module of a large system with thousands of users, which is now in use in his company. The cryptographic
keys are created from the product of two primes, and are believed to be secure because there is no known method for factoring such a product effectively.

What Odd Even did not think of, was that both factors in a key should be large, not just their product. It is now possible that some of the users of the system have weak keys. In a desperate attempt not to be fired, Odd Even secretly goes through all the users
keys, to check if they are strong enough. He uses his very poweful Atari, and is especially careful when checking his boss' key.
Input

The input consists of no more than 20 test cases. Each test case is a line with the integers 4 <= K <= 10100 and 2 <= L <= 106. K is the key itself, a product of two primes. L is the wanted minimum size of the factors
in the key. The input set is terminated by a case where K = 0 and L = 0.
Output

For each number K, if one of its factors are strictly less than the required L, your program should output "BAD p", where p is the smallest factor in K. Otherwise, it should output "GOOD". Cases should be separated by a line-break.
Sample Input
143 10
143 20
667 20
667 30
2573 30
2573 40
0 0

Sample Output
GOOD
BAD 11
GOOD
BAD 23
GOOD
BAD 31


题意:输入两个数K和L,K是两个素数的乘积(这句话告诉我们,这个K的因子除了1和它本身就只有这两个素数了),然后就是问你这两个素数是不是都比L大,如果是那么输出GOOD,不是那就输出BAD+最小的那个素数~

思路:首先我们想一下,可以打一个素数表,从最小的开始枚举,如果K能够整除这个素数,那么说明这个素数就是K的最小的素数了。然后直接和L比较就可以了。

不过人家K给了100位呐,普通的方法肯定是不行的了。我们这就把整除换成取模为0,这个是等价的,但是取模就不一样辣,我们可以用乘10取余法,当然这里是超时的,所以我们只能用乘千取余法辣~其实多少位都是可以的,确保不超时就好啦。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN=1000000+10;
bool prim[MAXN];
int primnum[MAXN];
int pcnt,cnt;
int num[50];
void get_prim()//欧拉筛
{
pcnt=0;
int i,j;
for(i=2; i<=1000000; ++i)
{
if(prim[i])continue;
primnum[pcnt++]=i;
for(j=i*2; j<=1000000; j+=i)prim[j]=1;
}
}
char k[110];
int l;
int main()
{
int i,j;
get_prim();//素数打表
while(~scanf("%s %d",k,&l))
{
if(k[0]=='0'&&!l)break;
int len=strlen(k);
cnt=0;
for(i=0; i<len; i+=3)//3个一分,乘10取余会超时呐
{
int h=0;
for(j=i; j<i+3&&j<len; ++j)
{
h=h*10+k[j]-'0';
}
num[cnt++]=h;
}
int ml=0,x=num[cnt-1];//表示最后可能不满3位,这里记录一下最后一位的位数
while(x)
{
ml++;
x/=10;
}
int flag=1;//默认就是最小素数比L大的
for(i=0; i<pcnt; ++i)//枚举素数
{
if(primnum[i]>=l)break;//确定符合条件,小优化
int h=0;
for(j=0; j<cnt-1; ++j)//乘千取余
{
h=(h*1000+num[j])%primnum[i];
}//最后的一个需要特殊处理一下
if(ml==1)h=(h*10+num[j])%primnum[i];
else if(ml==2)h=(h*100+num[j])%primnum[i];
else h=(h*1000+num[j])%primnum[i];
if(!h)//找到最小的那个素数了,肯定是小于L的,不符合条件
{
flag=0;
break;
}
}
if(flag)printf("GOOD\n");
else printf("BAD %d\n",primnum[i]);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj 组合数学