实验4-2-3 验证“哥德巴赫猜想” (20 分)

数学领域著名的“哥德巴赫猜想”的大致意思是:任何一个大于2的偶数总能表示为两个素数之和。比如:24=5+19,其中519都是素数。本实验的任务是设计一个程序,验证20亿以内的偶数都可以分解成两个素数之和。

输入格式:

输入在一行中给出一个(2, 2 000 000 000]范围内的偶数N

输出格式:

在一行中按照格式“N = p + q”输出N的素数分解,其中p ≤ q均为素数。又因为这样的分解不唯一(例如24还可以分解为7+17),要求必须输出所有解中p最小的解。

输入样例:

24

输出样例:

24 = 5 + 19

代码:

# include <stdio.h>
# include <stdlib.h>
# include <math.h>

typedef long long int long_int;
int judge_is_prime(int x){
    
    
	int isPrime = 1,i = 3;
	if(x == 1 || x % 2 == 0 && x != 2) isPrime = 0;
	else {
    
    
		for(;i<=sqrt(x);i+=2){
    
    
			if(x % i == 0){
    
    
				isPrime = 0;
				break;
			}
		}
	}
	return isPrime;
}

int main() {
    
    
	long_int N,p,q;
	scanf("%lld",&N);
	// 现在需要编写一个函数判断数是否是素数
	for (p=2;p<=N/2;p++) {
    
    
		// p是较小的一方 
		q = N - p;
		// 成功从n**2级别降低到n层面 
		if (judge_is_prime(p) && judge_is_prime(q)) {
    
    
			printf("%lld = %lld + %lld\n",N,p,q);
			break;
		}
	}
	return 0;
}

提交截图:

在这里插入图片描述

解题思路:

这道题让我清楚的认识到了算法的重要性!下面是解决这道题时遇到的一些问题:
① 下面是最开始编写的代码,时间复杂度大约 O ( n 2 ) O(n^{2}) O(n2)

# include <stdio.h>
# include <stdlib.h>

typedef long long int long_int;
int judge_is_prime(int a) {
    
    
	int i,value = 1;
	if (a == 2) {
    
    
		value = 1;
	}else {
    
    
		for (i=2;i<a;i++) {
    
    
			if (a % i == 0) {
    
    
			// 能被[2,i)因子整除则不是素数 
				value = 0;
			}
		}
	}
	return value;
} 

int main() {
    
    
	long_int N,p,q;
	scanf("%lld",&N);
	// 现在需要编写一个函数判断数是否是素数
	for (p=2;p<N;p++) {
    
    
		for (q=N-1;q>=2;q--) {
    
    
			if (judge_is_prime(p) && judge_is_prime(q) && p + q == N) {
    
    
				goto sum;
			}
		}
	}
	sum:printf("%d = %d + %d\n",N,p,q);
	return 0;
}

直接报错:在这里插入图片描述

在这里插入图片描述
② 后来对算法改进,发现第二层循环不需要,因为p +q == N,于是算法成为O(n)层级!在这里插入图片描述

③ 发现还是有问题,将goto语句去除还是不行,于是意识到是函数编写的问题,于是将判断素数的循环范围从i < n变成i < sqrt(n),这样发现第四个案例又出问题了,于是再次修改函数的判断条件,改为从3开始,逐次加2……终于通过了!难顶

猜你喜欢

转载自blog.csdn.net/weixin_43862765/article/details/114643785