北理18计算机上机——哥德巴赫猜想

脑子太笨,耗时5h,仍有很多地方冗余,可抽取。
相当于对每个偶数的各组素因子依次与后续的各个偶数的各组素因子进行统计,类似于多重循环统计。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
using namespace std; 
#define MAXN 10

bool judge(int n){//判断素数 
	int i;
	if(n < 2){
		return false;
	}
	for(i = 2; i <= sqrt(n); ++i){
		if(n % i == 0){
			return false;
		}
	}
	return true;
}
struct num{//存储每个偶数的素数分解因子
	int n;
	int ele[MAXN][2];
	int count;
	num(){
		count = 0;
	}
};
struct PAIR{
	int num;
	int times;
	PAIR(int n, int t){
		num = n;
		times = t;
	}
	bool operator< (PAIR pa) const{
		if(times == pa.times){
			return num < pa.num;
		}
		return times < pa.times;
	}
};

num nums[23];

void init(){
	int i, j, k = 0;
	int count = 0;
	bool flag = false;//标记 
	for(i = 6; i <= 50; i += 2){//为每个偶数初始化素数因子 
		count = 0;
		for(j = 2; j <= i / 2; ++j){
			if(judge(j) && judge(i - j)){
				nums[k].n = i;
				nums[k].ele[count][0] = i - j;
				nums[k].ele[count][1] = j;
				++count;
			}
		} 
		nums[k].count= count;
		++k; 
	}	
}

queue<map<int, int> > census(int s, int e){
	queue<map<int, int> > q;
	int i, j, k;
	for(i = 0; i < nums[s].count; ++i){//统计第一个偶数的各组素因子 
		map<int, int> m;
		int n1, n2;
		n1 = nums[s].ele[i][0];
		n2 = nums[s].ele[i][1];
		if(!m.count(n1)){
			m[n1] = 1;
		}else{
			m[n1]++;
		}
		if(!m.count(n2)){
			m[n2] = 1;
		}else{
			m[n2]++;
		}
		q.push(m);
	}
	for(i = s + 1; i <= e; ++i){//统计后续各组的素因子个数之和 
		int q_size = q.size();//此处取出其大小,以免后面大小变化 
		for(j = 0; j < q_size; ++j){
			map<int, int> temp = q.front();
			q.pop();
			for(k = 0; k < nums[i].count; ++k){//后面每组素因子(两个数)都要重新申请一个map 
				map<int, int> temp2 = temp;
				int n1, n2;
				n1 = nums[i].ele[k][0];
				n2 = nums[i].ele[k][1];
				if(!temp2.count(n1)){
					temp2[n1] = 1;
				}else{
					temp2[n1]++;
				}
				if(!temp2.count(n2)){
					temp2[n2] = 1;
				}else{
					temp2[n2]++;
				}
				q.push(temp2);
			}
		}
	} 
	return q;
}

int main(int argc, char *argv[]) {
	init();
	int s, e, i;
	while(cin>>s>>e){
		if(s % 2 == 1){//去掉开头和结尾的奇数 
			s += 1;			
		}
		if(e % 2 == 1){
			e -= 1;
		}
		queue<map<int, int> > q;
		q = census((s - 6) / 2, (e - 6) / 2);//返回还未排序的素因子统计 
		
		while(!q.empty()){
			map<int, int> m = q.front();
			q.pop();
			priority_queue<PAIR> qu; 
			map<int, int>::iterator it;
			for(it = m.begin(); it != m.end(); ++it){//对统计结果按要求进行排序,排序要求在结构体中实现 
				PAIR pa(it -> first, it -> second);
				qu.push(pa);
			}
			while(!qu.empty()){
				PAIR pa = qu.top();
				qu.pop();
				cout<<pa.num<<" "<<pa.times<<" ";
			}
			cout<<endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值