icodelab 数字拆分(数据加强了一点,题目也变了一点)
描述
小明在做了哥德巴赫猜想那一题之后,他发现很多数都可以分解成4个素数的和,例如:12=3+3+3+3; 18=2+2+3+11;那么是不是所有的数都满足这样的要求?给你一个数,请你判断是否能够分解成4个素数和。
输入
多组数据(不超过50000组)每行输入一个正整数n,最后一行输入0表示输入结束。
输出
对于每行的输入数据,如果该数能够分解成4个素数,请输出4个素数(形如a b c d的式子,要求a<=b<=c<=d),如果有多个同时满足条件组合,选a最小的那一组,如果a相同那么选b最小的那一组,以此类推。
输入样例 1
18 6 0
输出样例 1
2 2 3 11 NO
提示
0 < n < 10,000,000。
思路:
先用筛法求出素数,然后特判特殊的几个素数,再分别两个偶数的两个素数(哥德巴赫猜想:任一大于2的偶数都可写成两个质数之和)
代码:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=10000000; bool u[N+10]; int su[5000000], num; void prepare() { int i,j; memset(u,true, sizeof(u)); for(i=2; i<=10000000; i++) { if(u[i]) su[++num]=i; for(j=1; j<=num; j++) { if(i*su[j]>N) break; u[i*su[j]]=false; if(i%su[j]==0) break; } } } int main() { prepare(); int n,i,j,k; while(scanf("%d",&n)!=EOF&&n>0) { if(n<8) { puts("NO"); continue; } if(u[n-6]) printf("2 2 2 %d\n",n-6); else if(u[n-7]) printf("2 2 3 %d\n",n-7); else if(u[n-8]) printf("2 3 3 %d\n",n-8); else { if(n%2==0) { printf("2 2 "); n-=4; } else { printf("2 3 "); n-=5; } for(i=1; i<=num; i++) { if(su[i]*2>n) break; if(u[n-su[i]]) { printf("%d %d\n",su[i],n-su[i]); break; } } } } return 0; }