POJ 2536 大数取模运算

来源:互联网 发布:mac照片拷贝到移动硬盘 编辑:程序博客网 时间:2024/06/01 08:45

The Embarrassed Cryptographer
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 13356 Accepted: 3630

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
Source

Nordic 2005
题意:
给你一个数,这个数是由两个素数相乘得来的,问另一个数字是否比这两个数字里小的那个大,如果是,输出BAD + 那个数字。如果不是,输出GOOD。
题解:
我们首先用埃式筛法把检测范围里的所有素数都打出来。然后我们用一个数组去保存这个大数。但是我们用千位制度去保存。根据同余模定理:

以下运算都在mod M的条件下进行
当a = c,b = d时
a + b = c + d
a*b = c*d
现在有一个数abcd是千位制的数字,它的十进制的数字N为
a*(1000^3) + b*(1000^2) + c*(1000^1) + d*(1000^0)
我们要求N%M
即为
(a*(1000^3) + b*(1000^2) + c*(1000^1) + d*(1000^0))%M

=

a*(1000^3)%M + b*(1000^2)%M + c*(1000^1)%M + d*(1000^0)%M

=
a%M*(1000^3)%M + b%M*(1000^2)%M + c%M*(1000^1)%M + d%M

所以我们有:
k1 = a%M
k2 = k1*1000%M
k3 = k2*1000%M
k4 = k3*1000%M
k4即为最终结果,如果M为一素数且最终结果为0。则这是一个素因子。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <map>#include <queue>#include <vector>#include <sstream>#define f(i,a,b) for(i = a;i<=b;i++)#define fi(i,a,b) for(i = a;i>=b;i--)using namespace std;int p[1000100];int a[200];char s[200];void init(){    memset(p,0,sizeof(p));    p[1] = 1;    int k = 2,i;    for(;k<=1000100;k++){        if(p[k]==0){            for(i = k*2;i<=1000100;i+=k){                p[i] = 1;            }        }    }}int cnt(int k,int len){    int i;    int tem = a[len-1]%k;    fi(i,len-2,0){        tem = (tem*1000+a[i])%k;    }    return tem;}int main(){    init();    int b;    while(~scanf("%s %d",s,&b)&&(s[0]!='0'||b!=0)){        int len = strlen(s);        int i,j = 0;        for(i = len-1;i>=0;i-=3){            int tem;            if(i-2>=0)                tem = (s[i-2]-'0')*100+(s[i-1]-'0')*10+s[i]-'0';            else if(i-1>=0)                tem = (s[i-1]-'0')*10+s[i]-'0';            else if(i>=0)                tem = s[i]-'0';            a[j++] = tem;        }        int ok = 0;        f(i,2,b-1){            if(p[i]==0){                if(cnt(i,j)==0){                   ok = 1;                   break;                }            }        }        if(ok)            printf("BAD %d\n",i);        else            printf("GOOD\n");    }    return 0;}
0 0
原创粉丝点击