一、题目详情
问题描述:素数对猜想
让我们定义为:,其中是第i个素数。显然有,且对于n>1有是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N
(<),请计算不超过N
的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数N
。
输出格式:
在一行中输出不超过N
的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
代码长度限制:16 KB
时间限制:200 ms
内存限制:64 MB
二、题目解析
代码:
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#define LEN sizeof(struct Data)
int main()
{
/*
* num:正整数(输入数据)
* sturct Data:用于存储一系列素数的结构体类型(动态链表节点)
** int x:结构体变量,用于存储素数
** struct Data *next:结构体成员变量,用于链接结构体变量
* struct Data *head, *p1, *p2:用于创建动态链表时所需的结构体指针
* index:数组input的索引值,index+1为素数的个数
* sum:存储满足猜想的素数对的数量
* i,j:循环变量
*/
int num;
int i, j, n;
int index = -1, sum = 0;
struct Data
{
int x;
struct Data *next;
};
struct Data *head, *p1, *p2;
//获取正整数(输入数据)
scanf("%d", &num);
for(i=2;i<=num;i++)//逐一判别<=num内的每一个整数i
{
//判别是否为素数:在2到sqrt(n)之间,如果i能被j整除,为非素数,否则为素数
n = (int)sqrt(i);
for(j=2;j<=n;j++)
if(i%j == 0)//非素数
break;
if(j>n)//素数
{
p1 = (struct Data *)malloc(LEN);
p1->x = i;
if(index == -1)
head = p1;
else
p2->next = p1;
p2 = p1;
index++;
}
p2->next = NULL;
}
//寻找满足猜想的素数对
p1 = head;
while(p1->next != NULL)
{
p2 = p1->next;
if((p2->x - p1->x) == 2)
sum++;
p1 = p2;
}
printf("%d", sum);
return 0;
}
提交结果(分数/满分):
20/20
提示:
1. 判断素数的问题
判别素数的方法有很多,如果采用最常规的方法,测试结果可能会出现超时的问题,例如下述的方法1,就会出现超时问题。
方法1:
相关代码:
for(j=2;j<i;j++)
if(i%j == 0)//非素数
break;
运行结果:
测试点5:运行超时
表明:您的程序未能在规定时间内结束程序。 原因在于判别素数的方法过于繁琐。
方法2:(本题采用的方案,但不是最优方案)
相关代码:
n = (int)sqrt(i);
for(j=2;j<=n;j++)
if(i%j == 0)//非素数
break;
运行结果,不再赘述。
2. 数组定义的问题
1) 方案一
相关代码如下:
定义静态数组:
int input[10000];
经测试,100000以内的素数个数不超过10000,故数组input的大小固定为10000。
存储素数:
if(j>n)
input[++index] = i;
输出素数对的数量:
if(index > 0)
for(i=0;i<index;i++)
if(input[i+1] - input[i] == 2)
sum++;
printf("%d", sum);
输入样例1:
20
输出样例1:
4
输出结果:
输入样例2:
100000
输出样例2:
1224
2) 方案二
相关代码如下:
定义指针:
int* input = (int *)malloc(sizeof(int) * (index+1));
存储素数:
if(j>n)
input[++index] = i;
输出素数对的数量:
if(index > 0)
for(i=0;i<index;i++)
if(input[i+1] - input[i] == 2)
sum++;
printf("%d", sum);
输入样例1:
20
输出样例1:
4
提交结果:
输入样例2:
100000
输出样例2(PAT平台):
1224
输出样例2(Visual C++ 6.0环境):
注:在Visual C++ 6.0环境下,输出样例2没有任何输出结果,程序异常退出,其原因与存储素数的方式有关。经测试,数组input只能存储945个元素,即最后一个素数为7477。原因不详,高手指点,拜谢!
3) 方案三(本题采用的方案)
相关代码如下:
定义结构体:
struct Data
{
int x;
struct Data *next;
};
struct Data *head, *p1, *p2;
存储素数:
if(j>n)
{
p1 = (struct Data *)malloc(LEN);
p1->x = i;
if(index == -1)
head = p1;
else
p2->next = p1;
p2 = p1;
index++;
}
p2->next = NULL;
输出素数对的数量:
p1 = head;
while(p1->next != NULL)
{
p2 = p1->next;
if((p2->x - p1->x) == 2)
sum++;
p1 = p2;
}
printf("%d", sum);
输入样例1:
20
输出样例1:
4
提交结果:
输入样例2:
100000
输出样例2:
1224