孪生素数问题
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
写一个程序,找出给出素数范围内的所有孪生素数的组数。一般来说,孪生素数就是指两个素数距离为2,近的不能再近的相邻素数。有些童鞋一看到题就开始写程序,不仔细看题,咱们为了遏制一下读题不认真仔细的童鞋,规定,两个素数相邻为1的也成为孪生素数。
-
输入
-
第一行给出N(0<N<100)表示测试数据组数。
接下来组测试数据给出m,表示找出m之前的所有孪生素数。
(0<m<1000000)
输出
- 每组测试数据输出占一行,该行为m范围内所有孪生素数组数。 样例输入
-
1 14
样例输出
-
4
-
第一行给出N(0<N<100)表示测试数据组数。
我采用的思想是动态规划,用空间 去换时间
#include<stdio.h>//312 4536 时间 内存
#define N 1000005
int b[N] = { 0 };
int sum = 0;
int dp[100000];
int main() {
int judge(int a);
void set();
set();
int n;
scanf("%d", &n);
while (n--) {
int m;
scanf("%d", &m);
int mid;
int low = 0, hight = m;
while (low <= hight) {// 因为b 数组是有序的, 所以采用二分查找法
if (m == 1) {
printf("0\n");
break;
}
mid = (low + hight) / 2;
if (b[mid] == 0)hight = mid - 1; // 假如b[mid] 等于 0 ,说明范围太大了。缩小范围
else if (b[mid] > m&&b[mid - 1] <= m) { // 如果 m 在 他们之间 则返回 b[mid - 1] 的组数
printf("%d\n", dp[mid - 1]);
break;
}
else if (b[mid] == m) {
printf("%d\n", dp[mid]);
break;
}
else if (m < b[mid])hight = mid - 1;
else if (m > b[mid])low = mid + 1;
}
}
return 0;
}
int judge(int a) { // 判断是否为素数, 如果不是返回 1
if (a == 1)return 1;
for (int i = 2; i*i <= a; i++) {
if (a%i == 0)return 1;
}
return a;
}
void set() {
// 初始化 1000000 以内的素数, 并判断 每个素数之前有多少对孪生素数。用数组dp 记录下每个素数对应的组数
int k = 0;
for (int i = 2; i < N; i++) {
int temp;
temp = judge(i);//判断是否位素数。不是返回1.
if (temp != 1) {
b[++k] = temp;
if (b[k - 1] != 0 && b[k] - b[k-1] <= 2 && b[k] - b[k-1] > 0){
sum++;//判断相邻两个素数差。
dp[k] = sum;
}
else dp[k] = sum;
}
}
}