试题描述
任何大于2的偶数,都可以写成两个素数之和(俗称1+1)。
给定一个偶数,输出它的猜想式子。请使用循环来实现。
例如:2008=5+2003(如果有多个表达式,输出前一个加数最小的表达式)
输入
输入一个偶数n,且2 < n <= 10000。
输出
输出满足歌德巴赫猜想的第一个加数最小的表达式。
输入示例
2008
输出示例
2008=5+2003
数据范围
对于100%的数据,2 < n <= 10000
这是一道考察循环的C语言题目,对于初次接触循环的初学者并不简单。用到了多层循环和跳出循环的方法。
提示
质数(素数)的定义:只有两个正因数(1和自己)的自然数即为质数。
注意1不是质数!
判断一个数是否为质数有三种方法,第一种方法也是最简单的方法(适合初学者),判断一个整数m是否是素数,只需把 m 被 2 ~ m-1 之间的每一个整数去除,如果都不能被整除,那么 m 就是一个素数。
第二种方法因为如果 m 能被 2 ~ m-1 之间任一整数整除,其二个因子必定有一个小于或等于根号下m ,另一个大于或等于根号下m,所以只需把m被2~根号m之间的每一个整数去除,如果都不能被整除,那么 m 就是一个素数。第二种方法用到了函数sqrt。sqrt(m)=m开方,输出的是double形数据,还需调用math.h,在第一行加上#include<math.h>方可调用。这是一种改进的算法,能比第一种方法节省不少时间。
第三种方法是筛法,这里针对初学者不再介绍。
c语言代码(初学者看这个)
#include<stdio.h>
int main()
{
int n;
int i,j,k;
int a,b;
int flag=0;
scanf("%d",&n);/*输入要被分解成两个质数的数 */
for (i=2;i<=n/2;i++) /*注意题目只需输出前面较小的数 ,故从2到n/2*/
{
for (j=2;j<n;j++) /*判断i是否为质数*/
{
if (i%j==0&&i!=j)
break;
if (j>=n-1) /*当i为质数,把i的值赋给a,b等于n-a*/
{
a=i;
b=n-i;
for (k=2;k<=b;k++) /*判断b是否为质数*/
{
if (b%k==0&&b!=k)
break;
if (k>=b-1)
{
printf("%d=%d+%d",n,a,b);
flag=1; /*只需输出一个值,通过flag跳出最外层关于i的循环*/
break;
}
}
break;
}
}
if (flag==1)
break;
}
return 0;
}
这里用了第一种方法判断素数,因为2也是素数,而被试数从2开始,而2能被2整除,所以要加上限定条件除数不能等于被试数。
难点在于判断b是否为质数,关于跳出循环,可以用goto,但不推荐。
法2(函数法)
#include<stdio.h>
#include<math.h>
int primecheck(int x)
{
int i;
double a=sqrt(x);
for (i=2; ;i++)
{
if (x%i==0&&x!=i)
break;
if (i>a)
{
return 1;
}
}
return 0;
}
int main()
{
int n,i;
int flag1,flag2;
scanf("%d",&n);
for (i=2;i<=n/2;i++)
{
flag1=primecheck(i);
flag2=primecheck(n-i);
if (flag1==flag2&&flag1==1)
{
printf("%d=%d+%d",n,i,n-i);
break;
}
}
return 0;
}
比第一种方法简单不少,但需要函数的知识。