URAL1356(数论)
题意:给一个整数N(2 ≤ N ≤ 109),求至少可以找到几个素数的相加和为N,并输出各个素数。
解题思路:这题用到了有名的哥德巴赫猜想:任一大于5的整数都可写成三个素数之和,任一大于2的偶数都可写成两个素数之和。从这个猜想中可以得到,任何一个整数N(N>=2)最多由三个素数相加构成。要分情况考虑:
1. 如果N为偶数,1)如果N==2,直接输出;
2)如果N>2,那么N一定可以写成两个素数的和;
2.如果N为奇数,1)如果N自身就是素数,则直接输出;
2)如果N由两个素数构成,这两个素数只可能是:2 和 N-2;
3)N为三个素数之和。
View Code
1 #include<iostream>
2 #include<cstdio>
3 #include<cmath>
4 using namespace std;
5 int f(int n)//判断n为素数
6 {
7 int i;
8 for(i=2;i<=sqrt(1.0*n);i++)
9 if(n%i==0) return 0;
10 return 1;
11 }
12 int main()
13 {
14 int n,m,i,j;
15 scanf("%d",&m);
16 while(m--)
17 {
18 scanf("%d",&n);
19 if(n%2==0)
20 {
21 if(n==2) printf("2\n");
22 else if(n==4) printf("2 2\n"); //大于2的偶数可以为两个素数之和
23 else
24 {
25 for(i=3;i<n;i=i+2) //简化程序
26 if(f(i)&&f(n-i))
27 { printf("%d %d\n",i,n-i); break;}
28 }
29 }
30 else
31 {
32 if(f(n)) printf("%d\n",n); //自身为素数
33 else if(f(n-2)) printf("2 %d\n",n-2); //由两个素数之和组成
34 else if(f(n-4)) printf("2 2 %d\n",n-4); //由三个素数之和组成
35 else
36 {
37 for(i=3;i<n;i=i+2) //简化程序
38 {
39 if(f(i))
40 {
41 for(j=3;j<n;j=j+2)
42 if(f(j)&&f(n-i-j))
43 { printf("%d %d %d\n",i,j,n-i-j); break; }
44 }
45 break;
46 }
47 }
48 }
49 }
50 return 0;
51 }
2 #include<cstdio>
3 #include<cmath>
4 using namespace std;
5 int f(int n)//判断n为素数
6 {
7 int i;
8 for(i=2;i<=sqrt(1.0*n);i++)
9 if(n%i==0) return 0;
10 return 1;
11 }
12 int main()
13 {
14 int n,m,i,j;
15 scanf("%d",&m);
16 while(m--)
17 {
18 scanf("%d",&n);
19 if(n%2==0)
20 {
21 if(n==2) printf("2\n");
22 else if(n==4) printf("2 2\n"); //大于2的偶数可以为两个素数之和
23 else
24 {
25 for(i=3;i<n;i=i+2) //简化程序
26 if(f(i)&&f(n-i))
27 { printf("%d %d\n",i,n-i); break;}
28 }
29 }
30 else
31 {
32 if(f(n)) printf("%d\n",n); //自身为素数
33 else if(f(n-2)) printf("2 %d\n",n-2); //由两个素数之和组成
34 else if(f(n-4)) printf("2 2 %d\n",n-4); //由三个素数之和组成
35 else
36 {
37 for(i=3;i<n;i=i+2) //简化程序
38 {
39 if(f(i))
40 {
41 for(j=3;j<n;j=j+2)
42 if(f(j)&&f(n-i-j))
43 { printf("%d %d %d\n",i,j,n-i-j); break; }
44 }
45 break;
46 }
47 }
48 }
49 }
50 return 0;
51 }