您的位置:首页 > 其它

poj2635 同余定理 + 素数筛法

2017-02-14 13:20 267 查看
      题意:给定一个数,这个数是两个素数的乘积,并给定一个限制L,问是否两个素数中存在小于L的数,若存在输出较小质数,否则打印‘GOOD’。

    思路:

1 . x = a * b, a和b都是素数,那么x只能分解为(1,x)或则(a,b),因为 x 只有四个因子1,a,b,x。

2 . 判定某大数y能否被x整除,可以通过求余是否为0判断。大数求余的方法在我的上一篇文章中有证明。

3 . 素数打表,方便快速判断某个数是否为质数。

根据第一个结论,可以知道如果某个素数(这个数小于限制L)能被大数整除,那么这个数就是最小质数,就可以结束判断。

AC代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 1000005;
int vis[maxn], prim[maxn], a[105];
char s[105];

int deal(int n){
int m = sqrt(n + 0.5);
memset(vis, 0, sizeof(vis));
for(int i = 2; i <= m; ++i) if(!vis[i])
for(int j = i*i; j <= n; j += i) vis[j] = 1;

int cnt = 0;
for(int i = 2; i < n; ++i){
if(!vis[i]) prim[cnt++] = i;
}
return cnt;
}

// 转换千进制
int turn(int n){
memset(a, 0, sizeof(a));
int c = 0;
int m = n % 3;
for(int i = 0; i < m; ++i) a[c] = a[c] * 10 + s[i] - '0';
if(m) ++c;
for(int i = m; i < n; i += 3){
for(int j = i; j < i + 3; ++j)
a[c] = a[c] * 10 + s[j] - '0';
++c;
}
return c;
}

bool mod(int x, int n) {
int m = 0;
for(int i = 0; i < n; ++i){
m = (m * 1000+ a[i]) % x;
}
if(m == 0) return true;
return false;
}

int main(){
int n = deal(maxn);
int h;
while(scanf("%s%d", s, &h) == 2 && h){
int len = strlen(s);
len = turn(len);
int flag = 1;
for(int i = 0; prim[i] < h && i < n; ++i) {
if(mod(prim[i], len)) {
printf("BAD %d\n", prim[i]);
flag = 0;
break;
}
}
if(flag) printf("GOOD\n");
}
return 0;
}

如有不当之处欢迎指出!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: