今天又做了一些整数的练习,而且还是关于整数中素数的练习,
习题如下:
1.验证;
2000以内的正偶数都能分解为两个素数之和(哥德巴赫猜想)
问题分析:
为了验证哥德巴赫猜想对2000以内的正整数都成立,要将整数分解为两部分,然后在判断分解出的两部分是否都为素数,若是则满足题意;否则,重新进行分解和判断;
为了提高运算效率,对整数判断由”从2 到整数的一半“ 改为”从2 到整数的平方根“
程序如下:
#include <stdio.h>
#include <math.h>
fflag(int i)
{
int j;
if(i <=1)
{
return 0;
}
if(i == 2)
{
return 1;
}
if(i%2 == 0)
{
return 0;
}
for(j = 3; j <=(int)(sqrt((double)i)+1); j= j+2)
{
if(i % j == 0)
{
return 0;
}
}
return 1;
}
int main()
{
int i;
int n;
for(i = 4; i <= 2000; i=i+ 2)
{
for(n = 2; n < i; n++)
{
if(fflag(n))
{
if(fflag(i-n))
{
printf("%d=%d+%d\n", i, n, i-n);
break;
}
}
if(n == i)
{
printf("error %d\n",i);
}
}
}
return 0;
}
fflag 函数是判断该整数是否为素数的。(下同)
2.可逆素数:
求四位的可逆素数,可逆素数是指:一个素数将其各个数字的顺序反过来构成的数还是素数;
问题分析:
本题重点不是判断素数的方法而是求一个整数的反序数;
求反序数的方法是从整数的末尾截取最后一位,每截取一次,整数缩小10倍,将截取的数字作为新的整数的最后一位(新的整数扩大十倍加上被截取的数字)。
这样原来的整数被从低到高被不断截取,并依次作为新的整数从高到低的各位数字。
程序如下:
#include <stdio.h>
#include <math.h>
fflag(int i)
{
int j;
if(i <=1)
{
return 0;
}
if(i == 2)
{
return 1;
}
if(i%2 == 0)
{
return 0;
}
for(j = 3; j <=(int)(sqrt((double)i)+1); j= j+2)
{
if(i % j == 0)
{
return 0;
}
}
return 1;
}
int main()
{
int i;
int count;
printf("There are invertable primes with 4 digits:\n");
for(count = 0, i = 1001; i <= 9999; i = i + 2)
{
if(fflag(i) == 1)
{
printf(count%9?"%3d:%d\n":"%3d:%d\n", ++count, i);
}
}
return 0;
}
3.回文素数:
回文素数是指一个素数它从左边读和右边读都一样。
问题分析:
本题的重点不是判断素数而是求回文数。实现思路是先求出一个整数的回文数,在判断是否为素数;
程序如下:
#include <stdio.h>
fflag(int i)
{
int j;
if(i <=1)
{
return 0;
}
if(i == 2)
{
return 1;
}
if(i%2 == 0)
{
return 0;
}
for(j = 3; j <=(int)(sqrt((double)i)+1); j= j+2)
{
if(i % j == 0)
{
return 0;
}
}
return 1;
}
int main()
{
int i;
int j;
int k;
int t;
int s;
printf("Following are palindrome prinmes not greater than 1000:\n");
for(i = 0; i <= 9; i ++)
{
for(j = 0; j <= 9; j++)
{
for(k = 0; k <= 9; k++)
{
s = i * 100 + j * 10 + k;
t = k * 100 + j * 10 + i;
if(i == 0 && j == 0)
{
t = t / 100;
}
else if( i == 0)
{
t = t / 10;
}
if(s > 10 && s == t && fflag(s))
{
printf("%d\t",s);
}
}
}
}
return 0;
}