Professional Documents
Culture Documents
+ =
=
n
i k
k i i S
1
) (
S(i) = i((i+1) + (i+2) + + n) _(a
1
+ a
2
+ + a
m
)
2
= a
1
2
+ a
2
2
+ + a
n
2
+ a1a2 + a1a3 + +a1an
// Find the sum of all the primes below two million.
#include <iostream>
#include <math.h>
using namespace std;
const int mn = 200;
int a[mn];
int Diff1(int n) {
int s = 0;
int i, j;
for (i = 1; i < n; ++i)
for(j = i+1; j <= n; ++j) s += i*j;
return 2*s;
}
int Diff2(int n) {
int s;
int i;
a[n] = n;
for (i = n-1; i > 0; --i) a[i] = i+a[i+1];
s = a[2];
for(i = 2; i < n; ++i) s += i*a[i+1];
return 2*s;
}
main() {
cout << endl << Diff1(100);
cout << endl << Diff2(100);
cout << endl << " Fini"; cin.get();
return 0;
}
Problem 7
28 December 2001
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6
th
prime is 13. What is the
10001
th
prime number?
Phng n 1. Sng, sau duyt ly s th n. Trong khong 1..200000 c 17984 s nguyn t.
Phng n 2. NextPrime sinh s nguyn t st sau.
// Find the 10001-th prime number.
#include <iostream>
#include <math.h>
using namespace std;
const int mn1 = 200000;
const int mn2 = 20000;
char p[mn1+1];
int a[mn2];
void Eratosthenes(int n) {
int i, j, n2, c = (int)sqrt(n);
memset(p,0,sizeof(p));
for (i = 2; i < c; ++i)
if (p[i] == 0) {
n2 = n/i;
for (j = i; j <= n2; ++j) p[i*j] = 1;
}
}
int PrimeN1(int n) { // phuong an 1
int d = 0;
Eratosthenes(mn1);
for (int i = 2; i < mn1; ++i)
if (p[i] == 0) {
++d;
if (d == n) return i;
}
}
bool IsPrime(int m) {
int sq = (int)sqrt(m);
int i;
for (i = 1; a[i] <= sq; ++i)
if (m % a[i] == 0) return false;
return true;
}
// Biet k so nguyen to.
// Yim so thu k+1
int NextPrime(int k) {
int m = a[k];
do {
m += 2;
} while (!IsPrime(m));
return m;
}
int PrimeN2(int n) {
a[1] = 2; a[2] = 3; // Khoi tri voi 2 so ng to dau tien
int k = 2, m;
for (int i = 1; i <= n; ++i) {
m = NextPrime(k);
a[++k] = m;
}
return a[n];
}
main() {
cout << endl << PrimeN1(10001); // 104743
cout << endl << PrimeN2(10001); // 104743
cout << endl << " Fini"; cin.get();
return 0;
}
Problem 8
11 January 2002
Find the greatest product of five consecutive digits in the 1000-digit number.
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
Bin th 1. Tnh tng max ca k phn t lin tip. Ca s trt.
// Find the greatest sum of k consecutive digits
// in the n-digit number.
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <time.h>
using namespace std;
const char * fn = "Euler8.txt";
const int mn = 5000;
char a[mn];
int n; // so luong phan tu
int k; // chieu dai doan
inline bool IsDigit(char c) { return (c >= '0' && c <= '9'); }
void ReadData() {
ifstream f(fn);
int i = 0;
char c;
while (!f.eof()) {
f >> c;
if (IsDigit(c)) a[++i] = c-'0';
}
f.close();
for (i = 1; i <= n; ++i) cout << (int)a[i];
}
inline int Max(int a, int b) { return (a > b) ? a : b; }
int Sum() {
int s = 0, smax;
int i, j;
// Sum of the first k elements
for (i = 1; i <= k; ++i) s += a[i];
smax = s; i = 1;
for (j = k + 1; j <= n; ++j,++i) {
s = s + a[j] - a[i];
smax = Max(smax,s);
}
return smax;
}
main() {
time_t t1,t2;
t1 = time(NULL);
ReadData();
cout << endl << endl << Sum() << endl;
t2 = time(NULL);
float d = difftime(t2,t1);// sec.
cout << endl << " Time: " << d << " sec. " << endl;
cout << endl << " Fini";
cin.get();
return 0;
}
Bin th 2. Tch max ca k phn t lin tip. Ca s trt.
// Find the greatest product of k consecutive digits
// in the n-digit number.
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <time.h>
using namespace std;
const char * fn = "Euler8.txt";
const int mn = 5000;
char a[mn];
int n; // so luong phan tu
int k; // chieu dai doan
inline bool IsDigit(char c) { return (c >= '0' && c <= '9'); }
void ReadData() {
ifstream f(fn);
f >> n >> k; cout << endl << " n = " << n << " k = " << k <<
endl;
int i = 0;
char c;
while (!f.eof()) {
f >> c;
if (IsDigit(c)) a[++i] = c-'0';
}
f.close();
for (i = 1; i <= n; ++i) cout << (int)a[i];
}
inline int Max(int a, int b) { return (a > b) ? a : b; }
int Product() {
int s , smax = 0 ;
int i, j, d;
s = 1;
for (j = 1; j <= k; ++j) s *= a[j];
smax = Max(smax,s);
i = 1;
for (j = k+1; j <= n; ++j, ++i) {
if (a[i] > 0) s /= a[i];
else { // a[i] = 0
s = 1;
for (d = i+1; d < j; ++d) s *= a[d];
}
s *= a[j];
smax = Max(s,smax);
}
return smax;
}
main() {
time_t t1,t2;
t1 = time(NULL);
ReadData();
cout << endl << endl << Product() << endl;
t2 = time(NULL);
float d = difftime(t2,t1);// sec.
cout << endl << " Time: " << d << " sec. " << endl;
cout << endl << " Fini";
cin.get();
return 0;
}
Ci tin bin th 2. loi tr nhnTch max gx a[j] = 0.
Ch][ng trinhf tinhs car 2 ph][ng ans vaf xacs ddinhj v tr jmax (phn t cui dy t tch max).
// Find the greatest sum of k consecutive
// digits in the n-digit number.
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <time.h>
using namespace std;
const char * fn = "Euler8.txt";
const int mn = 5000;
char a[mn];
int n; // so luong phan tu
int k; // chieu dai doan
int jmax;
inline bool IsDigit(char c) { return (c >= '0' && c <= '9'); }
void ReadData() {
ifstream f(fn);
f >> n >> k; cout << endl << " n = " << n << " k = " << k <<
endl;
int i = 0;
char c;
while (!f.eof()) {
f >> c;
if (IsDigit(c)) a[++i] = c-'0';
}
f.close();
for (i = 1; i <= n; ++i) cout << (int)a[i];
}
inline int Max(int a, int b) { return (a > b) ? a : b; }
int Product1() {
int s , smax = 0 ;
int i, j, d;
s = 1;
for (j = 1; j <= k; ++j) s *= a[j];
if (smax < s) { smax = s; jmax = k; }
i = 1;
for (j = k+1; j <= n; ++j, ++i) {
if (a[i] > 0) s /= a[i];
else { // a[i] = 0
s = 1;
for (d = i+1; d < j; ++d) s *= a[d];
}
s *= a[j];
if (smax < s) { smax = s; jmax = j; }
}
return smax;
}
int Product2() {
int s , smax = 0 ;
int i = 0, j, d;
s = 1; d = 0;
for (j = 1; j <= n; ++j) {
if (a[j] == 0) {
i = j; s = 1; d = 0;
}
else { // s[j] > 0
s *= a[j];
++d;
if (d == k) {
if (smax < s) { smax = s; jmax = j; }
++i; s /= a[i]; --d;
}
}
}
return smax;
}
main() {
float d;
time_t t1,t2;
ReadData();
t1 = time(NULL);
cout << endl << endl << Product1() << " jmax = " << jmax <<
endl;
t2 = time(NULL);
d = difftime(t2,t1);// sec.
cout << endl << " Time: " << d << " sec. " << endl;
t1 = time(NULL);
cout << endl << endl << Product2() << " jmax = " << jmax <<
endl;
t2 = time(NULL);
d = difftime(t2,t1);// sec.
cout << endl << " Time: " << d << " sec. " << endl;
cout << endl << " Fini";
cin.get();
return 0;
}
Problem 9
25 January 2002
A Pythagorean triplet is a set of three positive integes (a, b, c), for which,
a
2
+ b
2
= c
2
.
For example, 3
2
+ 4
2
= 5
2
( 9 + 16 = 25).
There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc.
Nhn xt
1. Trong b ba Pithagor khng c 2 s bng nhau. Nu a = b th a c 2 = l s v t, khng phi s
nguyn. Nu a = c th b = 0, nu b = c th a = 0. T nhn xt ny ta c th quy nh 0 < a < b < c.
2. Nu tng a+b+c = k th nhn xt 1 cho ta 1 a m, a+1 b 2m, c = kab; m = k/3.
/*
There exists exactly one Pythagorean triplet
for which a + b + c = 1000.
Find the product abc.
-*/
#include <iostream>
#include <stdio.h>
using namespace std;
int Pit() {
const int k = 1000;
int a, b, c, c2, a2, ab2, lim, lim2;
lim = k/3; lim2 = 2*lim;
for (a = 1; a <= lim; ++a) {
a2 = a*a;
for (b = a+1; b <= lim2; ++b) {
ab2 = a2 + b*b;
c = k - a - b;
c2 = c*c;
if (c*c == ab2)
return (a * b * c);
}
}
return 0;
}
main() {
cout << endl << Pit();
cout << endl << " Fini";
cin.get();
return 0;
}
Problem 10
08 February 2002
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
// Find the sum of all the primes below two million.
#include <iostream>
#include <math.h>
using namespace std;
const int mn = 2000000;
char a[mn];
void Eratosthenes(int n) {
int i, j, n2, c = (int)sqrt(n);
memset(a,0,sizeof(a));
for (i = 2; i < c; ++i)
if (a[i] == 0) {
n2 = n/i;
for (j = i; j <= n2; ++j) a[i*j] = 1;
}
}
unsigned int Sum(int n) {
unsigned int s = 0;
Eratosthenes(n);
for (int i = 2; i <= n; ++i)
if (a[i] == 0) s += i;
return s;
}
main() {
int n = mn-1;
cout << Sum(n); // 1179908154
cout << endl << " Fini"; cin.get();
return 0;
}
Problem 11
22 February 2002
In the 20 20 grid below, four numbers along a diagonal line have been marked in red.
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
The product of these numbers is 26 63 78 14 = 1788696.
What is the greatest product of four adjacent numbers in any direction (up, down, left, right, or diagonally)
in the 20 20 grid?
Problem 14
05 April 2002
The following iterative sequence is defined for the set of positive integers:
n n/2 (n is even)
n 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 40 20 10 5 16 8 4 2 1
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not
been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
: Collatz Problem (Bi ton 3n+1).
Vi mi s t nhin n ta thc hin cc thao tc sau sinh ra dy s:
Nu n l th thay n bng 3n+1; ngc li, nu n chn th thay nn bng n/2.
Xc nh s n s 1000000 (1 triu) dy s sinh ra l di nht.
p s: n = 837799 sinh dy di 525 s.
Ch rn c th lc u gi tr n nh (di 1 triu), nhng sau mt s bc gi tr ny c th tng ln n
vi t. Th d,
837799 2513398 1256699 3770098 1885049 5655148 2827574 1413787 4241362
2120681 6362044 3181022 1590511 4771534 2385767 7157302 3578651
10735954 5367977 16103932 8051966 4025983 12077950 6038975 18116926
9058463 27175390 13587695 40763086 20381543 61144630 30572315 91716946
45858473 137575420 68787710 34393855 103181566 51590783 154772350
77386175 232158526 116079263 348237790 174118895 522356686 261178343
783535030 391767515 1175302546.
Thut ton
Ta tm gi dy sinh ra l dy 3n+1
Nhn xt.
1. Dy 3n+1 l dy khng lp, do sinh xui v sinh ngc u cc dy khng lp
Phng n 1: vt
Ta duyt vi mi n = 2..1000000 xc nh chiu di ln nht ca dy thu c theo quy tc ra trong bi.
rng khi n l ta tnh n = 3n+1. Ta thy n chn v n > n trong khi ta cn dy gim n 1. V vy, khi
n l ta tnh lun 2 bc n = 3n+1 v n = n/2 = 2n/2 + (n+1)/2 = n + (n+1)/2. Vi thi gian khng qu 1
bn c th tm ra p s n = 837799 t chiu di max = 525.
rng nu n chn th s(n) = s(n/2) + 1
n l th s(n) = s(n+(n+1)/2) + 2;
Nn chy trong Turbo Pascal v Free Pascal khng n nh.
Thay n/2 bng n >> 1 s nhanh hn l dng php chia.
(*------------------------------------------------
Problem Euler 14 Ver. 1
Find an integer n under one million that generates
the longest chain by the following rule
if n is even then replace n by n/2
else replace n by 3n + 1
--------------------------------------------------*)
const mn = 1000000;
function Try(n: longint): longint;
var d: longint;
begin
d := 1;
while (n > 1) do
if Odd(n) then
begin
d := d+2;
n := n+((n+1) shr 1);
end
else
begin
inc(d);
n := n shr 1;
end;
Try := d;
end;
procedure Find(mn: longint);
var i, d, dmax, imax: longint;
begin
dmax := 1; imax := 1;
for i := 2 to mn-1 do
begin
d := Try(i);
if (d > dmax) then
begin
dmax := d; imax := i;
end;
end;
writeln(dmax,' ', imax);
end;
BEGIN
Find(mn);
readln;
END.
/*------------------------------------------------
Problem Euler 14 Ver. 1
Find an integer n under one million that generates
the longest chain by the following rule
if n is even then replace n by n/2
else replace n by 3n + 1
--------------------------------------------------*/
#include <iostream>
#include <fstream>
#define Odd(n) (((n) & one) == one)
using namespace std;
typedef unsigned int UI;
const UI mn = 1000000;
const UI one = (UI)1;
int Try(UI n) {
int d = 1;
while (n > 1) {
if (Odd(n)) { d += 2; n = n+((n+1)>>1); }
else { d++; n >>= 1; }
}
return d;
}
void Find(int mn) {
UI i;
int d, dmax = 1, imax = 1 ;
for (i = 2; i < mn; ++i) {
d = Try(i);
if (d > dmax) {
dmax = d; imax = i;
}
}
cout << endl << imax << " " << dmax;
}
main() {
float d;
time_t t1,t2;
t1 = time(NULL);
Find(mn);
t2 = time(NULL);
d = difftime(t2,t1);// sec.
cout << endl << " Time: " << d << " sec. " << endl;
cout << endl << " Fini";
cin.get();
return 0;
}
Phng n 2. Dng quy hoch ng hn ch.
K hiu s(n) l chiu di dy 3n+1. Ta c ngay:
s(n) = s(n/2) + 1, nu n chn
s(n) = s(n+(n+1)/2) + 2, nu n l
Ta s dng mng a gm mn = 1 triu phn t, a[i] = s(i) v s lp cho n khi n < mn nh du
/*--------------------------------------------------------
Problem Euler 14 Ver. 2
Find an integer n under one million that generates
the longest chain by the following rule
if n is even then replace n by n/2
else replace n by 3n + 1
--------------------------------------------------------*/
#include <iostream>
#include <fstream>
#define Odd(n) (n & 1) == 1
#define Even(n) !Odd(n)
using namespace std;
typedef unsigned int UI;
const UI mn = 1000000;
UI a[mn];
int Try(UI n) {
int d = 1, v = n;
if (Even(v)) {
a[n] = a[v/2] + 1; return a[n];
}
while (v > 1) {
if (Odd(v)) { d += 2; v += ((v+1)>>1); }
else { d++; v >>= 1; }
if (v < n) {
if (a[v] > 0) {
a[n] = a[v] + d - 1;
return a[n];
}
}
}
a[n] = d;
return a[n];
}
int Test(UI n) {
int d = 1;
while (n > 1) {
if (Odd(n)) { d += 2; n += ((n+1)>>1); }
else { d++; n >>= 1; }
}
return d;
}
void Find(int mn) {
UI i;
int d, dmax = 1, imax = 1;
memset(a,0,sizeof(a));
a[1] = 1;
for (i = 2; i < mn; ++i) {
d = Try(i);
if (d > dmax) {
dmax = d; imax = i;
}
}
cout << endl << imax << " " << dmax;
}
main() {
float d;
time_t t1,t2;
t1 = time(NULL);
Find(mn);
t2 = time(NULL);
d = difftime(t2,t1);// sec.
cout << endl << " Time: " << d << " sec. " << endl;
cout << endl << " Fini";
cin.get();
return 0;
}
Phng n 3.
FromOne: Sinh dy ngc t 1. nh du di ca cc phn t c sinh mi trong dy.
Sau duyt li mng, xt nhng phn t cha nh du ta sinh xui dy v cng nh du cc phn t
c sinh trong dy.
/*------------------------------------------------
Problem Euler 14 Ver. 3
Find an integer n under one million that generates
the longest chain by the following rule
if n is even then replace n by n/2
else replace n by 3n + 1
--------------------------------------------------*/
#include <iostream>
#include <fstream>
#define Odd(n) (n & 1) == 1
#define Even(n) !Odd(n)
using namespace std;
typedef unsigned int UI;
const UI mn = 1000000;
const UI mn2 = mn+2;
UI len[mn];
UI q[mn];
UI v,r; // con tro ngan xep st
UI lenmax, imax;
void FromOne() {
UI x, y;
UI s;
memset(len,sizeof(len),0);
v = r = 0; len[1] = 1;
q[++v] = 1;
do {
x = q[++r]; s = len[x];
y = 2*x;
if (y < mn)
if (!len[y])
{ len[y] = s+1; q[++v] = y; }
if (Even(x)&&((x-1)%3==0)) {
y = (x-1)/3;
if (!len[y])
{ len[y] = s+1; q[++v] = y; }
}
} while (v != r);
lenmax = s ; imax = x;
}
void ToOne(UI n) {
int d = 1;
int x = n;
int s, i;
q[d] = n;
if (Even(x)) {
len[n] = len[x/2] + 1;
if (lenmax < len[n]) {
lenmax = len[n];
imax = n;
}
return;
}
while (x > 1) {
if (Odd(x)) { q[++d] = 3*x+1; x = q[d]/2; q[++d] = x; }
else { x >>= 1; q[d++] = x; }
if (x < mn)
if (len[x]) {
len[n] = len[x] + d - 1;
if (lenmax < len[n]) {
lenmax = len[n];
imax = n;
}
s = len[n]+1;
for (i = 2; i <= d; ++i)
if (q[i] < mn) len[q[i]] = s-i;
return;
}
}
}
void Find() {
UI i;
FromOne();
for (i = 2; i < mn; ++i)
if (len[i] == 0) ToOne(i);
cout << endl << " lenmax = " << lenmax << " imax = " <<
imax;
}
main() {
float d;
time_t t1,t2;
t1 = time(NULL);
Find();
t2 = time(NULL);
d = difftime(t2,t1);// sec.
cout << endl << " Time: " << d << " sec. " << endl;
cout << endl << " Fini";
cin.get();
return 0;
}
Problem 15
19 April 2002
Starting in the top left corner of a 2 2 grid, there are 6 routes (without backtracking) to the bottom right
corner.
How many routes are there through a 20 20 grid?
Thut ton
Ta gii bi ton tng qut vi li n v gm chiu di n, rng m. Trn li vung ny ta nh nhn cc
cnh n v nm ngang l D, dc l R. Mi ng i khng quay lui t gc trn tri n gc di phi u
phi qua ng n cnh ngang v m cnh dc. Bi ton quy v dng t hp nh sau. C th xy dng bao
nhiu xu k t di n+m t hai k t D v R trong c ng n k t D v m k t R. Nh vy ta ch cn
chn ng n v tr trong s cc v tr t 1..(n+m) in k t D. Cc v tr cn li ta in k t R.Vy p
s s l t hp chp 2 ca 2n
C
n
n+m
= (n+m)!/(n!m!) = ((n+1)(n+2)...(n+m))/m! (*)
Vi n = m = 20 ta phi tnh ton vi cc s ln ca t v mu s trong cng thc (*). Ta chn phng php
tnh khc, c th l ta dng tam gic Pascal. Tam gic Pascal c nhng tnh cht sau :
(T1) Dng th n c n+1 phn t m s t 0 n n.
(T2) Phn t th k trn dng n, C
k
n
= t hp chp k ca n phn t = s hng th k trong dng khai
trin ca nh thc (a+b)
n
= tng ca s hng th k v k-1 trn dng st trc, dng n-1 (C
k
n
= C
k
n-1
+ C
k-1
n-1
).
(T3) Mi dng l mt dy s c b tr i xng nhau. Tnh cht ny cho php ta ch cn xc
nh cc gi tr trn mt na dng.
2
3
4
5
6
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
7 1 6 15 20 15 6 1
// Problem Euler 15
#include <iostream>
#define Even(c) ((c)&1)==0
#define Odd(c) !Even(c)
const int maxN = 21;
int a[maxN];
using namespace std;
int Pas(int n, int m) {
int nm = n+m, i, i2, j;
a[0] = a[1] = 1;
for (i = 2; i <= nm; ++i) {
i2 = i/2;
a[i2] = (Odd(i)) ? a[i2]+a[i2-1] : 2*a[i2-1];
for (j = i2-1; j > 0; --j)
a[j] = a[j]+a[j-1];
}
return (n < m) ? a[n] : a[m];
}
main() {
cout << endl << Pas(2,2); // 407575348
cout << endl << " Fini";
cin.get();
return 0;
}
Problem 16
03 May 2002
2
15
= 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2
1000
?
Thut ton Tnh trc tip.
Khi tr a = 2;
lp n ln a = a * 2;
// Problem Euler 16
// Tnh tong cac chu so cua so 2^1000
#include <iostream>
const int maxN = 500;
int a[maxN];
int len;
using namespace std;
// 2^1
void Init() {
memset(a,0,sizeof(a));
a[0] = 2;
len = 1;
}
// a = 2*a
void Mult2() {
int c = 0;
for (int i = 0; i < len; ++i) {
c = (a[i]<<1) + c;
a[i] = c % 10;
c /= 10;
}
if (c) a[len++] = c;
}
int Sum(int n) {
int i,s = 0;
Init();
for (i = 2; i <= n; ++i)
Mult2();
for (i = 0; i < len ; ++i) s += a[i];
return s;
}
main() {
cout << endl << Sum(1000) << " len = " << len; // 1366, 302 chu
so
cout << endl << " Fini";
cin.get();
return 0;
}
Vit dy s
Nu s dng cc tm ba, trn mi tm ghi 1 ch s th ghi lin tip cc s t 1 n 10 ta cn 21 tm.
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5
Cn bao nhiu ba vit cc s t 1 n 1000?
Problem 18
31 May 2002
By starting at the top of the triangle below and moving to adjacent numbers on the row below, the
maximum total from top to bottom is 23.
3
7 4
2 4 6
8 5 9 3
That is, 3 + 7 + 4 + 9 = 23.
Find the maximum total from top to bottom of the triangle below:
75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
NOTE: As there are only 16384 routes, it is possible to solve this problem by trying
every route. However, Problem 67, is the same challenge with a triangle containing one-
hundred rows; it cannot be solved by brute force, and requires a clever method!)
Thut ton
c dn d liu tnh trng s ti mi nh k. nh trn cnh (nm ngoi cng 2 u) ch
c 1 cha. nh trong c 2 cha.
Nu k l nh u tin ca dng i th cha ca k l k-i+1. Nu k l nh cui cng ca dng
i th cha ca k l k-i. Nu nh k nm gia dng i th k c 2 cha l k-i v k-i+1.
// Problem Euler 16
// Tnh tong cac chu so cua so 2^1000
#include <iostream>
#include <fstream>
#define Max(a,b) ((a > b) ? a : b)
const int maxN = 5000;
const char * fn = "E18.inp";
int a[maxN];
using namespace std;
int MaxTotal(){
int n, i, j, x, k = 1, maxval = 0;
ifstream f(fn);
f >> n;
f >> x; a[k] = x;
for (i = 2; i <= n; ++i) {
f >> x; ++k; a[k] = a[k-i+1]+x;
for (j = 2; j < i; ++j) {
f >> x; ++k; a[k] = Max(a[k-i],a[k-i+1]) + x;
}
f >> x; ++k; a[k] = a[k-i] + x;
}
f.close();
for (j = 0; j < n; ++j)
maxval = Max(maxval,a[k-j]);
return maxval;
}
main() {
cout << endl << MaxTotal(); // 1074
cout << endl << " Fini";
cin.get();
return 0;
}
Problem 19
14 June 2002
You are given the following information, but you may prefer to do some research for yourself.
1 Jan 1900 was a Monday.
Thirty days has September,
April, June and November.
All the rest have thirty-one, Saving February alone,
Which has twenty-eight, rain or shine. And on leap years, twenty-nine.
A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec
2000)?
Problem 20
21 June 2002
n! means n (n 1) ... 3 2 1. Find the sum of the digits in the number 100!
n n! sum
1 1 1
2 2 2
3 6 6
4 24 6
5 120 3
6 720 9
7 5040 9
Thut ton
Lm trc tip. Biu din s ln.
// E20 Tong cc chu so cua n!
#include <iostream>
using namespace std;
const int mn = 200;
int a[mn];
int len;
void Print(char *msg) {
cout << msg;
for (int i = len-1; i >= 0; --i) cout << a[i];
cout << "(" << len <<")";
}
void Init() {
len = 1;
a[0] = 1;
}
// a = a * x
void Mult(int x) {
int c = 0, i;
for (i = 0; i < len; ++i) {
c = a[i]*x + c;
a[i] = c % 10;
c /= 10;
}
while (c) {
a[len++] = c % 10;
c /= 10;
}
}
int Sum(int n) {
int i;
Init();
for (i = 2; i <= n; ++i)
Mult(i);
int s = 0;
for (i = 0; i < len; ++i) s += a[i];
return s;
}
main() {
cout << Sum(100); // 648
cout << endl << " Fini !";
cin.get();
}
Problem 21. S thn thin
05 July 2002
Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).
If d(a) = b and d(b) = a, where a b, then a and b are an amicable pair and each of a and b are called
amicable numbers.
For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) =
284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.
Evaluate the sum of all the amicable numbers under 10000.
Thut ton
Nhn xt
5 cp s thn thin trong khong 1..10000
220 - 284
1184 - 1210
2620 - 2924
5020 - 5564
6232 - 6368
Tng: 31626.
Dng mng a nh du cc phn t duyt, gim s ln x l.
// E20 Amicable Numbers So than thien
#include <iostream>
#include <math.h>
using namespace std;
const int mn = 10000;
int a[mn+1];
// Tong cac uoc < n cua n
int Su(int n) {
int u, c = (int)sqrt(n), s;
if (n == 1) return 0;
s = 1;
if (c*c == n) { s += c; --c; }
for (u = 2; u <= c; ++u)
if (n % u == 0) s += u + (n/u);
return s;
}
int Ami(int n) {
int i, d, j, s = 0, v = 0;
memset(a,0, sizeof(a));
for (i = 2; i <= n ; ++i)
if (a[i] == 0) {
++v;
a[i] = 1; d = Su(i);
if (d <= n)
if (a[d] == 0) {
a[d] = 1; j = Su(d);
if (j == i && i != d) {
cout << endl << i << " " << d;
s += i + d;
}
}
}
cout << endl << " So lan duyet: " << v << endl;
return s;
}
main() {
cout << endl << Ami(mn); // 31626
cout << endl << " Fini !";
cin.get();
}
Problem 22
19 July 2002
Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand
first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each
name, multiply this value by its alphabetical position in the list to obtain a name score.
For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 =
53, is the 938th name in the list. So, COLIN would obtain a score of 938 53 = 49714.
What is the total of all the name scores in the file?
Problem 23. S hon thin
02 August 2002
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For
example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a
perfect number.
A number n is called deficient (ht, thiu) if the sum of its proper divisors is less than n and it is called
abundant (tri, di, di do) if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as
the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater
than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be
reduced any further by analysis even though it is known that the greatest number that cannot be expressed
as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
Thut ton
Chng trnh kho st cc loi s.
Scan: Duyt cc s t 1 n 28123. Gi Su(i) l tng cc c thc s ca s nguyn dng i. nh du mi
s i theo cc nhn:
a[i] = 0: nu i l s hon thin, tc l Su(i) = i;
a[i] = 1: nu i l s ht, tc l Su(i) < i;
a[i] = 2: nu i l s di, tc l Su(i) > i; ng thi nht ring cc s di a vo mng b. Gi k l bin m
cc s di, ta c mng b[1..k] cha ton s di.
Asum: Duyt cc cp s di b[i], b[j], 1 s i, j s k. nh du cc s l tng ca b[i] v b[j].
/*-------------------------------------------
E23 perfect Numbers So hoan thien
Su(n) = tong cac uoc that su cua n
- Su(n) = n: So hoan thien (perfect number)
- Su(n) < n: So hut (deficient)
- Su(n) > n: So doi (abundant)
So tong doi la so la tong cua 2 so doi.
Moi so tu nhien lon hon 28123 deu la so tong doi.
Tinh tong cua cac so khong tong doi.
6965 so abudant.
Tim duoc 1456 so
--------------------------------------------*/
#include <iostream>
#include <math.h>
using namespace std;
#define abundant 2
#define perfect 0
#define deficient 1
#define asum 4
const int mn = 28124;
int a[mn];
int b[mn]; // danh sach cac so abudant
int k;
// Tong cac uoc < n cua n
int Su(int n) {
int u, c = (int)sqrt(n), s;
if (n == 1) return 0;
s = 1;
if (c*c == n) { s += c; --c; }
for (u = 2; u <= c; ++u)
if (n % u == 0) s += u + (n/u);
return s;
}
int Scan() {
int i, d, k = 0;
memset(a,0,sizeof(a));
for (i = 1; i < mn; ++i) {
d = Su(i);
if (d == i) a[i] = perfect;
else if (d < i) a[i] = deficient;
else {
a[i] = abundant;
b[++k] = i;
}
}
return k;
}
void ShowAbudant() {
int i;
cout << endl << k << " so abudant: " << endl;
cout << endl; cin.get();
for (i = 1; i <= k; ++i) cout << b[i] << " ";
}
void ShowAll() {
int i;
cout << endl << " Danh sach tong the: " << endl;
for (i = 1; i < mn; ++i) {
cout << i << ":";
switch(a[i]) {
case perfect: cout << "p "; break;
case deficient: cout << "d "; break;
case abundant: cout << "a "; break;
}
}
}
// Cac so la tong cua 2 abudant
int Asum() {
int i, j, s;
for (i = 1; i <= k; ++i)
for (j = 1; j <= k; ++j) {
s = b[i]+b[j];
if (s < mn) a[s] = asum;
}
s = 0;
for (i = 1; i < mn; ++i)
if (a[i] != asum) {
s += i;
}
return s;
}
void TestAbudant() {
int i;
for (i = 1; i <= k; ++i) {
cout << endl << b[i] << " " << Su(b[i]); cin.get();
}
}
void Run() {
int i;
k = Scan();
cout << endl << endl << " Total: " << Asum(); // 4179871
}
main() {
Run();
cout << endl << " Fini !";
cin.get();
}
Problem 25
30 August 2002
The Fibonacci sequence is defined by the recurrence relation:
F
n
= F
n 1
+ F
n 2
, where F
1
= 1 and F
2
= 1.
Hence the first 12 terms will be:
F
1
=1, F
2
=1, F
3
=2, F
4
=3, F
5
=5, F
6
=8, F
7
=13, F
8
=21, F
9
=34, F
10
=55, F
11
=89, F
12
= 144.
The 12th term, F
12
, is the first term to contain three digits.
What is the first term in the Fibonacci sequence to contain 1000 digits?
Tnh trc tip
Ci t php cng v php gn cc s ln.
Tnh gn ng:
K hiu
2
5 1+
= o . Gi f
n
l s Fibonacci th n (tnh t 1). Dng qui np ton hc c th chng minh
c o
n-2
< f
n
s o
n-1
. Ta bit s ch s ca s nguyn dng n l int(lg(n))+1, trong int(x) l hm ly
phn nguyn ca s thc x, lg l hm logarithm c s 10 (trong C vit l log10).
V hm lg l ng bin nn bt phng trnh kp trn cho ta
(n-2)o + 1 < lg(f
n
) + 1 s (n-1)o +1.
/*-------------------------------------------
E25 Find the first term of Fibonacci sequence
to contain 1000 digits
--------------------------------------------*/
#include <iostream>
#include <math.h>
using namespace std;
#define Max(a,b) ((a > b) ? a : b)
#define Min(a,b) ((a > b) ? b : a)
const int mn = 1000;
int lena, lenb, lenc;
int a[mn], b[mn], c[mn];
// c = a + b;
void Plus() {
memset(c,0,sizeof(c));
lenc = Max(lena, lenb);
int i, v = 0;
for (i = 0; i < lenc; ++i) {
v = v + a[i] + b[i];
c[i] = v % 10;
v /= 10;
}
while (v) { c[lenc++] = v % 10; v /= 10;}
}
int Fib(int n) {
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0] = b[0] = 1;
lena = lenb = 1;
lenc = 0;
int i = 2;
while (lenc < n) {
Plus();
memcpy(a, b, sizeof(b)); lena = lenb;
memcpy(b, c, sizeof(c)); lenb = lenc;
++i;
}
return i;
}
// f(n) <= x^(n-1); m = lg(f{n)) = (n-1)lg(x)
// m/lg(x)+1
main() {
cout << endl << endl ;
int n = 1000; int m;
float x = (sqrt(5)+1)/2;
float y = log10(x);
cout << endl << (int)pow(x,n-2) << " " << (int)pow(x,n-1);
cout << endl << (int(n/y) + 1);
cout << endl << Fib(n); // 4785
cout << endl << lena << " " << lenb << " " << lenc;
cout << endl << " Fini !";
cin.get();
}
Problem 26
13 September 2002
A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with
denominators 2 to 10 are given:
1
/
2
= 0.5
1
/
3
= 0.(3)
1
/
4
= 0.25
1
/
5
= 0.2
1
/
6
= 0.1(6)
1
/
7
= 0.(142857)
1
/
8
= 0.125
1
/
9
= 0.(1)
1
/
10
= 0.1
Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that
1
/
7
has a 6-digit
recurring cycle.
Find the value of d 1000 for which
1
/
d
contains the longest recurring cycle in its decimal fraction part.
Fib
Dy s nguyn c gi l ta Fibonacci ...,f
-2
, f
-1
, f
0
, f
1
, f
2
, ... c tnh cht f
i
= f
i-1
+f
i-2
. Bit 5 gi tr
i, f
i
, j, f
j
, n, i j. Vit hm Fib(i, f
i
, j, f
j
, n) tnh f
n
?
Th d Fib(0, 7, -5, -1, 3) = 29. ngha: Bit f
0
= 7, f
-5
= -1 ta tnh c f
3
= 29
-1 2 1 3 4 7 11 18 29
Thut ton
Gi s i < j.
Nu n = i ta cho kt qu fn = fi,
Nu n = j ta cho kt qu fn = fj,
Nu n i ta x l nh sau.
Gi c
i
, i = 1, 2, l dy Fibonacci chun, tc l dy c
1
=1, c
2
=1, c
3
= c
2
+c
1
= 2, ,..., c
i
= c
i-1
+c
i-2
; i = 3, 4,
. Ta tm cch biu th dy ta Fibonacci qua dy Fibonacci chun.
t k = j-i. t f
i
= a, f
i+1
= b. Ta c
f
i
= a,
f
i+1
= b,
f
i+2
= f
i+1
+ f
i
= a + b,
f
i+3
= f
i+2
+ f
i+1
= (a+b) + b = a + 2b = a.c
2
+ b.c
3
f
i+4
= f
i+3
+ f
i+2
= (a.c
2
+ b.c
3
) + (a+b) = a(c
2 + 1
) + b(c
3
+1) = a.c
3
+ b.c
4
.
Tng qut:
f
j
= f
i+k
= a.c
k-1
+ b.c
k
= f
i
.c
k-1
+ b.c
k
(*)
T y suy ra b = (f
j
- f
i
.c
k-1
)/c
k
Bit f
i
= a, f
i+1
= b ta d dng tnh c n nh sau:
Nu i < n ta tnh dn f
i
theo chiu xui, t i = i+2 n n:
if (i < n) {
for (i = i+2; i <= n; ++i) {
t = a + b; a = b; b = t;
}
return b;
}
Nu i > n ta tnh theo chiu ngc ta tnh dn f
i
theo chiu ngc, t i = i-1 lui v n:
// i > n
for (i = i-1; i >= n; --i) {
t = b - a; b = a; a = t;
}
return a;
Chng trnh
/*------------------------------------------------
Fibonacci
--------------------------------------------------*/
#include <iostream>
using namespace std;
int Fb(int k, int fi, int fj) {
int t = 1, s = 1;
int i, c;
for (i = 3; i <= k; ++i) {
c = t + s;
t = s; s = c;
}
return (fj-fi*t)/s;
}
int Fib(int i, int fi, int j, int fj, int n) {
if (n == i) return fi;
if (n == j) return fj;
int t, k, a, b;
if (i > j) {
t = i; i = j; j = t;
t = fi; fi = fj; fj = t;
}
k = j-i;
a = fi;
b = Fb(k,fi, fj); // a = f(i) , b = f(i+1)
if (i < n) {
for (i = i+2; i <= n; ++i) {
t = a + b; a = b; b = t;
}
return b;
}
// i > n
for (i = i-1; i >= n; --i) {
t = b - a; b = a; a = t;
}
return a;
}
main() {
cout << endl << Fib(5, 76, 0, 7, 3);
cout << endl << " Fini";
cin.get();
return 0;
}
Sudoku
/*
Name: Sudoku
Copyright:
Author: Nguyen Xuan Huy
Date: 25/08/10 14:50
Description: Search Binary Trees
*/
#include <iostream>
#include <fstream>
#include <math.h>
const char BL = 32;
const int mn = 10;
typedef int mi1[mn];
typedef mi1 mi2[mn];
mi2 s,a;
mi1 c;
using namespace std;
// Hien thi
void Print(mi2 s) {
cout << endl;
for (int i = 0 ; i < 9; ++i) {
cout << endl;
for (int j = 0; j < 9; ++j)
cout << s[i][j] << BL;
}
}
// cac mau da dung tren dong i
void Row(int i) {
for (int j = 0; j < 9; ++j) ++c[s[i][j]];
}
// cac mau da dung tren dong j
void Colum(int j) {
for (int i = 0; i < 9; ++i) ++c[s[i][j]];
}
// cac mau da dung trong khoi (x,y)
void Square(int x, int y) {
for (int i = 3*x; i < 3*x+3; ++i)
for (int j = 3*y; j < 3*y+3; ++j)
++c[s[i][j]];
}
bool TestRow() {
for (int i = 0; i < 9; ++i) {
memset(c,0,sizeof(c));
for (int j = 0; j < 9; ++j)
if (c[s[i][j]]) return false;
else ++c[s[i][j]];
}
cout << endl << "Rows OK";
return true;
}
bool TestColum() {
for (int j = 0; j < 9; ++j) {
memset(c,0,sizeof(c));
for (int i = 0; i < 9; ++i)
if (c[s[i][j]]) return false;
else ++c[s[i][j]];
}
cout << endl << "Colums OK";
return true;
}
bool TestSquare() {
int i, j, x, y;
for (x = 0; x < 3; ++x)
for (y = 0; y < 3; ++y) {
memset(c,0,sizeof(c));
for (i = 3*x; i < 3*x+3; ++i)
for (j = 3*y; j < 3*y+3; ++j)
if (c[s[i][j]]) return false;
else ++c[s[i][j]];
}
cout << endl << "Squares OK";
return true;
}
bool Test() {
return TestRow() && TestColum() && TestSquare();
}
void Print(mi1 a, int d, int c) {
for (int i = d; i <= c; ++i) cout << a[i] << BL;
}
// xac dinh mau cho o (i,j)
int FindColour(int i, int j) {
memset(c,0,sizeof(c));
Row(i); Colum(j); Square(i/3,j/3);
// Print(c,1,9); cin.get();
for (int k = s[i][j]+1; k <= 9; ++k)
if (c[k] == 0) return k;
return 0;
}
/*---------------------------
Sinh nhanh 1 cau hinh chuan
+-----------------------+
| 1 2 3 | 4 5 6 | 7 8 9 |
| 4 5 6 | 7 8 9 | 1 2 3 |
| 7 8 9 | 1 2 3 | 4 5 6 |
|-------+-------+-------|
| 2 3 4 | 5 6 7 | 8 9 1 |
| 5 6 7 | 8 9 1 | 2 3 4 |
| 8 9 1 | 2 3 4 | 5 6 7 |
|-------+-------+-------|
| 3 4 5 | 6 7 8 | 9 1 2 |
| 6 7 8 | 9 1 2 | 3 4 5 |
| 9 1 2 | 3 4 5 | 6 7 8 |
+-----------------------+
*/
void Gen(int n) {
int n2 = n*n;
for (int i = 0; i < n2; i++)
for (int j = 0; j < n2; j++)
s[i][j] = (i*n + i/n + j) % n2 + 1;
}
/*------------------------------
s: ma tran Sudoku
a: ma tran cho truoc
cac gia tri a[i] > 0 can bao luu
--------------------------------*/
void Read(){
ifstream f("sudoku.inp");
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j) {
f >> s[i][j]; a[i][j] = s[i][j];
}
f.close();
}
// Chuyen tu o (i,j) sang o ke tiep
void Next(int &i, int &j) {
if (j < 8) ++j;
else { ++i; j = 0; }
}
// chuyen tu o (i,j) sang o ke truoc
void Pred(int &i, int &j) {
if (j > 0) --j;
else { --i; j = 8; }
}
void Run() { // back tracking
Read(); // Print(s); Print(a);
int i = 0, j = 0, cc;
while(true) {
if (i < 0) {
cout << endl << " Vo nghiem"; return;
}
if (i > 8) {
Print(s);
if (Test()) cout << endl << "Ok";
else cout << endl << "ERROR !!!";
return;
}
if (a[i][j]) Next(i,j); // mau co dinh
else { // can tim mau cho o [i][j]?
cc = FindColour(i,j);
if (cc > 0) { // tim duoc
s[i][j] = cc; Next(i,j);
}
else { // ko tim duoc
s[i][j] = 0;
Pred(i,j); // lui 1 o
while (i >= 0 && a[i][j]) Pred(i,j);
}
}
}
}
main() {
Run();
cout << endl << " Fini "; cin.get();
return 0;
}