题意:给定一个数,这个数是两个素数的乘积,并给定一个限制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;
}
如有不当之处欢迎指出!