标签:
Timus Online Judge 网站上有这么一道题目:1356. Something Easier。这道题目的输入是一组 2 到 109 之间整数,对于每个输入的整数,要求用最少个数的素数的和来表示。这道题目的时间限制是 1 秒。
我们知道著名的哥德巴赫猜想是:
任何一个充分大的偶数都可以表示为两个素数之和
于是我们有以下的 C 语言程序(1356.c):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#include
<stdio.h> #include
<stdlib.h> #include
<math.h> #include
<time.h> #define
PRIME_MAX 10000 #define
PRIME_COUNT 1229 typedef unsigned long long U8; typedef char bool ; const bool true =
1; const bool false =
0; bool *
getSieve( int max) { static bool sieve[(PRIME_MAX
>> 1) + 1]; int i,
j, imax = sqrt (max); for (i
= 3; i <= imax; i += 2) if (!sieve[i
>> 1]) for (j
= i * i; j <= max; j += i << 1) sieve[j >> 1] = true ; return sieve; } int *
getPrimes( int max) { static int primes[PRIME_COUNT
+ 1]; bool *sieve
= getSieve(max); int i,
j = 0; for (primes[j++]
= 2, i = 3; i <= max; i += 2) if (!sieve[i
>> 1]) primes[j++] = i; return primes; } U8
modMultiply(U8 a, U8 b, U8 m) { return a
* b % m; } U8
modPow(U8 a, U8 b, U8 m) { U8
v = 1, p; for (p
= a % m; b > 0; b >>= 1, p = modMultiply(p, p, m)) if (b
& 1) v = modMultiply(v, p, m); return v; } bool witness(U8
a, U8 n) { U8
n1 = n - 1, s2 = n1 & -n1, x = modPow(a, n1 / s2, n); if (x
== 1 || x == n1) return false ; for (;
s2 > 1; s2 >>= 1) { x
= modMultiply(x, x, n); if (x
== 1) return true ; if (x
== n1) return false ; } return true ; } U8
random(U8 high) { return (U8)(high
* ( rand ()
/ ( double )RAND_MAX)); } //
n, an integer to be tested for primality //
k, a parameter that determines the accuracy of the test bool probablyPrime(U8
n, int k) { if (n
== 2 || n == 3) return 1; if (n
< 2 || n % 2 == 0) return 0; while (k--
> 0) if (witness(random(n
- 3) + 2, n)) return false ; return true ; } bool isPrime( int n) { return probablyPrime(n,
2); } int outEven( int primes[], int n) { int i,
p, q; for (i
= 0; (p = primes[i]) != 0; i++) if (isPrime(q
= n - p)) return printf ( "%d
%d" ,
p, q); return printf ( "error:%d" ,
n); } int main( void ) { int t,
n, *primes = getPrimes(PRIME_MAX); srand ( time (NULL)); scanf ( "%d" ,
&t); while (t--
> 0) { scanf ( "%d" ,
&n); if (isPrime(n)) printf ( "%d" ,
n); else if ((n
& 1) == 0) outEven(primes, n); else if (isPrime(n
- 2)) printf ( "2
%d" ,
n - 2); else printf ( "3
" ),
outEven(primes, n - 3); puts ( "" ); } return 0; } |
上述程序分析如下:
上述程序在 Timus Online Judge 网站的运行时间是 0.015 秒。
版权声明:本文为博主http://www.zuiniusn.com 原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u013141940/article/details/47254053