现在的位置: 首页 > 综合 > 正文

158 整数的素数和分解问题

2018年01月19日 ⁄ 综合 ⁄ 共 1314字 ⁄ 字号 评论关闭

58、整数的素数和分解问题
歌德巴赫猜想说任何一个不小于 6 的偶数都可以分解为两个奇素数之和。
对此问题扩展,如果一个整数能够表示成两个或多个素数之和,则得到一个素数和分解式。
对于一个给定的整数,输出所有这种素数和分解式。
注意,对于同构的分解只输出一次(比如 5 只有一个分解 2 + 3,而 3 + 2 是 2 + 3 的同构
分解式)。
例如,对于整数 8,可以作为如下三种分解:
(1) 8 = 2 + 2 + 2 + 2
(2) 8 = 2 + 3 + 3

(3) 8 = 3 + 5

/*
58、整数的素数和分解问题
歌德巴赫猜想说任何一个不小于 6 的偶数都可以分解为两个奇素数之和。
对此问题扩展,如果一个整数能够表示成两个或多个素数之和,则得到一个素数和分解式。
对于一个给定的整数,输出所有这种素数和分解式。
注意,对于同构的分解只输出一次(比如 5 只有一个分解 2 + 3,而 3 + 2 是 2 + 3 的同构
分解式)。
例如,对于整数 8,可以作为如下三种分解:
(1) 8 = 2 + 2 + 2 + 2
(2) 8 = 2 + 3 + 3
(3) 8 = 3 + 5

参考别人的 似懂未懂 
*/
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define M 100000
#define N 100
int vis[M],prime[N];
int k,c;
int dp[N][N],ans[M];  
//dp[i][j] i是质数 j是位置 
void getPrime()
{
	int i,j;
	memset(vis,0,sizeof(vis));
	k=0;
	for(i=2;i<M;i++)
	{
		if(!vis[i])
		{
			prime[k++]=i;
			for(j=2*i;j<M;j+=i)
				vis[j]=1;	
		}
		if(k>=100)
			break;
	}
}

void printAll(int n,int l,int k)//k表示的是小于n的最大质数的位置 
{  
    int i;  
    if(!n)//0输出 
	{  
        for(i=l-1;i>0;i--)  
            printf("%d+",ans[i]); 
		printf("%d",ans[0]); 
        printf("\n");  
        c++;  
        return;  
    }  
    for(i=0;i<=k;i++)
	{  
        if(dp[n][i])
		{  
            ans[l]=prime[i];  
            printAll(n-prime[i],l+1,i);  
        }  
    }  
}  
 
int main()					
{							 
	int n,i,j,z;
	getPrime();
	while(1)
	{
		printf("请输入正整数n(0结束)\n");
		scanf("%d",&n);
		if(n==0) break;
		
		c=0;  
        memset(dp,0,sizeof(dp));  
        for(i=0;prime[i]<=n;i++)  
            dp[prime[i]][i]=1;  //表示dp[i][J] i是质数 j是质数的位置 
   
        for(i=2;i<=n;i++)//所有数 
		{  
            for(j=0;prime[j]<i;j++)//质数的位置j 
			{  
                for(z=j;z>=0;z--) //小于n的所以数的 质数组合 
                    dp[i][j]|=dp[i-prime[j]][z];//z是质数的位置    
            }  
        }  
        printAll(n,0,j-1);  
        printf("%d总共:%d种分法!\n",n, c);  
    }  
	return 0;
}

抱歉!评论已关闭.