您的位置:首页 > 其它

POJ-2635 The Embarrassed Cryptographer 大数取模

2012-09-12 20:22 399 查看
题意是给定一个大数,这个数是由两个素数相乘得到的,现在问你这个大数的分解是否存在一个素数小于给定的数。由于这个给定的数L小于10^6,所以我们就可以打表到10^6,最好打的大一点(比10^6大的最小的素数即可),这样可以方便跳出循环。

接下来,对于每一个数,我们直接对其小于L的所有素数进行一次试除,看是否余数为零。这里用到了一个大数取模的运算,一个大数对一个int型的数。过程是这样的,我们可以把一个数(abc...xyz)看作是10*(abc...xy)+z --> 10*(10*(abc...x)+y)+z,一直这样下去,我们在从最里面取模开始即可。

代码如下:

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define eps (1e-6)
#define MAXN 1100000
using namespace std;

bool p[MAXN+5];
int rec[90000], idx;

void getprime() {
idx = -1;
for (int i = 2; i <= MAXN; ++i) {
if (!p[i]) {
rec[++idx] = i;
}
for (int j = 0; rec[j]*i <= MAXN; ++j) {
p[rec[j]*i] = 1;
if (i % rec[j] == 0) {
break;
}
}
}
}

int Mod(char key[], int L) {
int len = strlen(key+2), ret = 0, beg = 2;
if (len % 3 == 1) {
beg = 0;
} else if (len % 3 == 2) {
beg = 1;
}
len += 2;
for (int i = beg; i < len; i+=3) {
int temp = (key[i]-'0')*100+(key[i+1]-'0')*10+(key[i+2]-'0');
ret = ((long long)ret*1000 + temp) % L;
}
return ret;
}

int main() {
getprime();
int L, ret, flag;
char key[150] = {'0', '0'};
while (scanf("%s %d", key+2, &L), (key[2]-'0') | L) {
flag = 0;
for (int i = 0; rec[i] < L; ++i) {
if (Mod(key, rec[i]) == 0) {
ret = rec[i];
flag = 1;
break;
}
}
if (flag) {
printf("BAD %d\n", ret);
} else {
puts("GOOD");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: