You are on page 1of 72

Thi HSG Quc gia 2010

CCKLK: Dy con chung khng lin k di nht


Cho dy s nguyn dng x = (x
1
, x
2
, ..., x
n
). Dy y = (x
i1
, x
i2
, ..., x
ik
) c gi l dy con khng lin k ca
dy x nu 1 s i1 < i21 < ... < ik1 s n. Cho 2 dy s nguyn a gm n phn t v b gm m phn t. Xc
nh chiu di k ca dy con chung khng lin k di nht ca a v b. 2 s m, n s 1000, 1s ai, bi s 10000.
CCKLK.INP CCKLK.OUT Gii thch
5 6
1 5 3 8 2
2 1 3 4 2 6
2 CCKLK.INP: Dng u: n m. T dng th hai tr i: Dy s a,
tip n l dy s b.
CCKLK.OUT: k.
Thut ton
Quy hoch ng.
Gi d(i,j) l p s ca bi ton khi xt hai dy a[1..i] v b[1..j]. Ta c:
- Nu i 0 th ta quy c d(i,j) = 0,
- Nu a[i] = b[j] th d(i,j) = d(i2,j2),
- Nu a[i] b[j] th d(i,j) = max { d(i1,j), d(i,j1) }.
ci t ta dng 3 mng mt chiu x, y v z vi ngha x[j] = d(i2,j), y[j] = d(i1,j) v z[j] = d(i,j). Khi
h thc trn c vit l:
- Nu i 0 th ta quy c d(i,j) = 0,
- Nu a[i] = b[j] th d(i,j) = d(i2,j2) ng vi z[j] = x[j2],
- Nu a[i] b[j] th d(i,j) = max { d(i1,j), d(i,j1) } ng vi z[j] = max { y[j], z[j1] }.
Mun trnh cc php copy d liu t y sang x; t z sang y v t x sang z ta ch cn tro i cc con tr
mng.
phc tp
O(n.m)
Chng trnh Pascal
(* CCKLK.PAS
k: chieu dai day con chung khong lien ke dai nhat
cua hai day so nguyen duong a[1..n], b[1..m]
*)
const fn = 'ccklk.inp'; gn = 'ccklk.out';
bl = #32; nl = #13#10; mn = 1001;
type int = integer;
mi1 = array[0..mn] of int;
var
n, m: int;
a, b: mi1;

function Max(a,b: int): int;
begin if a >= b then Max := a else Max := b; end;

procedure Doc;
var i: int;
f: text;
begin
assign(f,fn); reset(f);
read(f,n, m);
writeln(n,bl,m);
for i := 1 to n do read(f,a[i]);
for i := 1 to m do read(f,b[i]);
write(nl, 'a: ');
for i := 1 to n do write(a[i],bl);
write(nl, 'b: ');
for i := 1 to n do write(b[i],bl);
close(f);
end;

procedure Ghi(k: int);
var g: text;
begin
assign(g,gn); rewrite(g);
writeln(g,k); close(g);
end;

(*
d(i,j) = dap so cua bai toan voi a[1..i], b[1..j]
d(i,j) = d(i-2,j-2) + 1, if a[i] = b[j]
= Max begin d(i,j-1), d(i-1,j) end;, elsewhere
= 0, if i < 1 || j < 1
*)

function QHD: int;
var i, j, v: int;
c: array[1..3] of mi1;
x, y, z, t: int;
begin
x := 1; y := 2; z := 3;
{ Init i = 0 }
fillchar(c[x],sizeof(c[x]), 0);
{ Init i = 1 }
c[y][0] := 0; v := 0;
for j := 1 to m do
begin
if (a[1] = b[j]) then v := 1;
c[y][j] := v;
end;
v := 0;
for i := 2 to n do
begin
c[z][0] := 0;
if (a[i] = b[1]) then v := 1;
c[z][1] := v;
for j := 2 to m do
if (a[i] = b[j]) then c[z][j] := c[x][j-2]+1
else c[z][j] := Max(c[z][j-1],c[y][j]);
t := x; x := y; y := z; z := t;
end;
QHD := c[y][m];
end;

BEGIN
Doc;
Ghi(QHD);
write(nl,' Fini ');
readln;
END.
Chng trnh CPP
/* DevC++ CCKLK.CPP
k: chieu dai day con chung khong lien ke dai nhat
cua hai day so nguyen duong a[1..n], b[1..m]
*/
#include <fstream>
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L E
const char * fn = "ccklk.inp";
const char * gn = "ccklk.out";
const int mn = 1001;
int n, m;
int a[mn],b[mn];
// P R O T O T Y P E S
void Doc();
int QHD(); // Quy hoach dong
void Ghi(int);
int Max(int,int);

// I M P L E M E N T A T I O N
int main() {
Doc();
Ghi(QHD());
cout << endl << " Fini ";
cin.get();
return 0;
}

int Max(int a, int b) { return (a >= b) ? a : b; }

void Doc() {
int i;
ifstream f(fn);
f >> n >> m;
cout << endl << n << " " << m;
for (i = 1; i <= n; ++i) f >> a[i];
for (i = 1; i <= m; ++i) f >> b[i];
cout << endl << "a: ";
for (i = 1; i <= n; ++i) cout << a[i] << " ";
cout << endl << "b: ";
for (i = 1; i <= m; ++i) cout << b[i] << " ";
f.close();
}

void Ghi(int k) {
ofstream g(gn);
g << k;
g.close();
}
/*
d(i,j) = dap so cua bai toan voi a[1..i], b[1..j]
d(i,j) = d(i-2,j-2) + 1, if a[i] = b[j]
= Max { d(i,j-1), d(i-1,j) }, elsewhere
= 0, if i < 1 || j < 1
*/

int QHD() {
int *x, *y, *z, *t;
int i, j , m1 = m+1, v ;
x = new int[m1];
y = new int[m1];
z = new int[m1];
// Init i = 0
memset(x,0,sizeof(int)*m1);
// Init i = 1
y[0] = 0; v = 0;
for (j = 1; j <= m; ++j) {
if (a[1] == b[j]) v = 1;
y[j] = v;
}
v = 0;
for (i = 2; i <= n; ++i) {
z[0] = 0;
if (a[i]==b[1]) v = 1;
z[1] = v;
for (j = 2; j <= m; ++j)
z[j] = (a[i] == b[j]) ? x[j-2]+1 : Max(z[j-1],y[j]);
t = x; x = y; y = z; z = t;
}
v = y[m];
delete x; delete y; delete z;
return v;
}
n nh
Cho th c hng gm n nh v m cung (u,v). Cho trc nh s. Mt nh d s c gi l n nh i
vi s nu c t nht hai ng i ngn nht t s ti d. Hy tnh k l s lng nh n nh i vi nh s.
2 s n s 10000, 1 s m s 50000.

ONDINH.INP ONDINH.OUT Gii thch
6 7 1
1 2
1 4
2 3
2 5
4 5
2 3
5 6
2 ONDINH.INP: Dng u: n m s. T dng th hai tr i:m cung
dng u v. C th c cc cung trng nhau (d tha).
ONDINH.OUT: k.
Th d cho bit: c 3 nh n nh i vi nh 1 l cc nh 5
v 6.
1 2 5; 1 4 5;
1 2 5 6; 1 4 5 6.


Thut ton
Dng mt bin th ca thut ton Dijkstra.

// Ondinh.CPP
// HSG 2010

#include <string.h>
#include <fstream>
#include <iostream>
//#include <mem.h>

using namespace std;

// D A T A A N D V A R I A B L E S

char * fn = "ondinh.inp";
char * gn = "ondinh.out";
const int mn = 10001;
const int mm = 50001;
typedef struct { int a, b; } cung;
cung c[mm];
int len[mn]; // len[i] chieu dai s => i
char mark[mn]; // mark[i] danh dau dinh i:
// Chua xet 0; Co trong hang doi q 1; Da xu li 2
int d[mn]; // d[i] so luong duong ngan nhat s => i
int q[mn]; // hang doi
int n, m, s ; // so dinh n, so cung m, dinh xuat phat s
// P R O T O T Y P E S
int main();
void Doc();
int XuLi();
int Min(int, int);
int BinSearch(cung [], int, int, int);
int Sanh(int,int,int,int);
void Ghi();

int main(){
Doc(); XuLi(); Ghi();
cout << endl << " Fini"; cin.get();
return 0;
}

int Min(int a, int b) { return (a <= b) ? a : b; }

void Ghi() {
int i, k = 0;
for (i = 1; i <= n; ++i)
if (d[i] > 1) ++k;
ofstream g(gn);
g << k;
g.close();
}

int XuLi() {
int i, j, k, v, r;
v = 0; r = 0;
memset(mark,0,sizeof(mark));
memset(d,0,sizeof(d));
len[s] = 0; d[s] = 1;
q[++v] = s;
while (r < v) { // 1
i = q[++r]; cout << endl << " Xet dinh " << i;
mark[i] = 2;
for (k = BinSearch(c,m,i,0); c[k].a == i; ++k) { // 2
j = c[k].b; // xet cac dinh j ke dinh i
if (mark[j] == 0) {
len[j] = len[i]+1; mark[j] = 1;
d[j] = d[i]; q[++v] = j;
}
else if (mark[j] == 1) {
if (len[i]+1 == len[j]) d[j]++;
}
} // 2
} // 1
for (i = 1; i <= n; ++i) cout << d[i] << " ";
}

int Sanh(int u1, int v1, int u2, int v2) {
if (u1 < u2) return -1;
if (u1 > u2) return 1;
// u1 == u2
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}

int BinSearch(cung c[], int k, int u, int v) {
int d = 1, m;
while (d < k) {
m = (d + k) / 2;
if (Sanh(c[m].a,c[m].b,u,v) < 0) d = m+1; else k = m;
}
return d;
}
void Doc() {
int i, j, u, v, k = 0;
ifstream f(fn);
f >> n >> m >> s;
cout << endl << n << " " << m << " " << s;
// The first edge (u,v)
f >> u >> v;
++k; c[k].a = u; c[k].b = v;
for (i = 2; i <= m; ++i) {
f >> u >> v;
j = BinSearch(c,k,u,v);
if (Sanh(c[j].a,c[j].b,u,v) != 0) {
if (Sanh(c[j].a,c[j].b,u,v) < 0) { ++k; c[k].a = u; c[k].b
= v; }
else {
memmove(&c[j+1], &c[j], (k-j+1)*sizeof(cung));// <mem.h>
c[j].a = u; c[j].b = v; ++k;
}
}
}
f.close();
m = k;
}



// Ondinh.CPP Phuong an cu
// HSG 2010

#include <string.h>
#include <fstream>
#include <iostream>
//#include <mem.h>

using namespace std;

// D A T A A N D V A R I A B L E S

char * fn = "ondinh.inp";
char * gn = "ondinh.out";
const int mn = 10001;
const int mm = 50001;
typedef struct { int a, b; } cung;
cung c[mm];
int p[mn];
char d[mn];
int s[mn];
int n, m, x; // so dinh n, so cung m, dinh xuat phat x
// P R O T O T Y P E S
int main();
void Doc();
int XuLi();
int Minp();
int Min(int, int);
int BinSearch(cung [], int, int, int);
int Sanh(int,int,int,int);
void Ghi();

int main(){
Doc(); XuLi(); Ghi();
cout << endl << " Fini"; cin.get();
return 0;
}

int Min(int a, int b) { return (a <= b) ? a : b; }

int Minp() {
int i, imin = 0;
for (i = 1; i <= n; ++i)
if (!d[i] && p[i] < p[imin]) imin = i;
d[imin] = 1;
return imin;
}

void Ghi() {
int i, k = 0;
for (i = 1; i <= n; ++i)
if (s[i] > 1) ++k;
ofstream g(gn);
g << k;
g.close();
}

int XuLi() {
int i, imin, j, k;
memset(d,0,sizeof(d));
for (i = 2; i <= n; ++i) s[i] = 0;
s[x] = 1;
p[0] = n+2; p[x] = 0;
for (i = 2; i <= n; ++i) p[i] = n+1;
for (i = 1; i <= n; ++i) {
imin = Minp();
for (k = BinSearch(c,m,imin,0); c[k].a == imin; ++k) {
j = c[k].b;
if (!d[j]) {
if (p[imin]+1 < p[j]) { p[j] = p[imin]+1; s[j] =
s[imin]; }
else if (p[imin]+1 == p[j]) ++s[j];
}
}
}
}

int Sanh(int u1, int v1, int u2, int v2) {
if (u1 < u2) return -1;
if (u1 > u2) return 1;
// u1 == u2
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}

int BinSearch(cung c[], int k, int u, int v) {
int d = 1, m;
while (d < k) {
m = (d + k) / 2;
if (Sanh(c[m].a,c[m].b,u,v) < 0) d = m+1; else k = m;
}
return d;
}
void Doc() {
int i, j, u, v, k = 0;
ifstream f(fn);
f >> n >> m >> x;
// The first edge (u,v)
f >> u >> v;
++k; c[k].a = u; c[k].b = v;
for (i = 2; i <= m; ++i) {
f >> u >> v;
j = BinSearch(c,k,u,v);
if (Sanh(c[j].a,c[j].b,u,v) != 0) {
if (Sanh(c[j].a,c[j].b,u,v) < 0) { ++k; c[k].a = u; c[k].b
= v; }
else {
memmove(&c[j+1], &c[j], (k-j+1)*sizeof(cung));// <mem.h>
c[j].a = u; c[j].b = v; ++k;
}
}
}
f.close();
m = k;
}

M s thu
Xt tp S gm tt c cc s 1..n trong h 36, 36 s n s 10
16
. Cho s m: 3 s m s 70. Xt dy s nguyn 1 < c
1

< c
2
< ... < c
k
< 36, k = (m1)/2( , x( l s nguyn ln nht khng vt qu x.
Chn cc s cha cc ch s < c1 cp cho 2 nhm 1 v 2 ri xa cc s ny. Chn cc s cha cc ch s
< c2 cp cho 2 nhm 3, 4.... Cc s cn li cp cho 1 hoc 2 nhm cui.
Nhm le: t nh, nhm chn: t ln.
Cho cc s h 10: n, m, ci, p v q. Xc nh m (h 36) cp cho ng th q nhm p.
Th d:
n = 50, m = 3, p = 2, q = 2, c1 = 16. 1d
Ct on
Cho hnh ch nht OABC, OA = n, OC = m, coi O l gc ta (0,0). Trong hnh CN cho k on thng
ng. Tm im P trn BA hoc BC on OP ct nhiu on nht.

on khc nhau
Cho dy a gm n s nguyn dng. Mt on ca dy a, k hiu a[i..j] l dy gm cc phn t ng lin
tip nhau trong dy a, k t phn t a
i
n phn t a
j
, a[i..j] = (a
i
, a
i+1
,...,a
j-1
, a
j
), 1 s i <= j s n. Hy tm
on di nht gm cc phn t i mt khc nhau.
1 s n, a
i
s 100000.
D liu vo: Tp vn bn diff.inp
- Dng u tin: s n.
- T dng th hai tr i: dy s a.
D liu ra: Tp vn bn diff.out cha 2 s:
- imax ch s u tin ca on di nht tm c trong dy a
- dmax s phn t ca don di nht.
Cc s trn cng dng cch nhau qua du cch.

diff.inp diff.out Gii thch
10
5 2 4 1 5
3 2 7 6 9
3
8
Tnh t phn t th 3 c c thy
8 s i mt khc nhau l
4 1 5 3 2 7 6 9

Thut ton
Ln lt c cc phn t a
i
ca dy a v nh du v tr xut hin ca a
i
trong dy thng qua mng p, p[a
i
] =
i. Vi th d cho, sau khi c v x l xong dy a ta phi thu c

i

1 2 3 4 5 6 7 8 9 10
a
i

5 2 4 1 5 3 2 7 6 9
p
4 2/7 6 3 1/5 9 8 0 10 0
p[2] = 2/7 cho bit s 2 lc u xut hin ti v tr 2 trong dy a, sau
xut hin ti v tr 7 trong dy a. p[8] = p[10] = 0 cho bit cc s 8 v 10
khng xut hin trong dy a.

Ta gi p l dy tr ngc hay dy v tr ca dy a. Ta x l tng on d ca a
i
nh sau. Mi on d s bao
gm mt dy lin tip cc phn t i mt khc nhau tnh t ch s i n j. Th d trn cho ta ln lt 3
on sau:
- on th nht d = a[1..4] = (5, 2, 4, 1), i = 1, j = 4,
- on th hai d = a[2..6] = (2, 4, 1, 5, 3), i = 2, j = 6,
- on th ba d = a[3..10] = (4, 1, 5, 3, 2, 7, 6, 9), i = 3, j = 10.
Mi on d c xc nh nh sau: Mi khi gp phn t a
j
u tin trng vi mt phn t trong dy tnh t
i th ta ct ra c on d = a[i..j1].
Vi mi on d[i..j] ta tnh s phn t ca on l ji+1 v cp nht gi tr dmax. khi tr cho on
tip theo, ta t i = p[a
j
]+1. Ch rng p[a
j
] l v tr xut hin ca gi tr lp a
j
.
phc tp
O(n)
Chng trnh Pascal
(* diff.pas
Tim doan dai nhat gom cac
phan tu doi mot khac nhau
*)

const fn = 'diff.inp'; gn = 'diff.out';
bl = #32; nl = #13#10;
mn = 100001;
var p: array[0..mn] of longint;
n: longint;
imax, dmax: longint;
{ imax - chi so dau tien cua doan dai nhat
dmax - so phan tu cua doan dai nhat }
f,g: text;

procedure Run;
var i, j, v, istart: longint;
begin
imax := 0; dmax := 0;
fillchar(p,sizeof(p),0);
assign(f,fn); reset(f);
readln(f,n);
read(f,v); { phan tu dau tien trong day }
p[v] := 1; istart := 1;
for i := 2 to n do
begin
read(f,v);
if (p[v] >= istart) then
begin
if (i-istart > dmax)then
begin
dmax := i-istart; imax := istart;
end;
istart := p[v]+1;
end;
p[v] := i;
end;
close(f);
i := n+1;
if (i-istart > dmax) then
begin
dmax := i-istart; imax := istart;
end;
assign(g,gn); rewrite(g);
write(g, imax, nl, dmax);
close(g);
end;

BEGIN
Run;
write(nl, ' Fini '); readln;
END.
Chng trnh CPP
/* DevC++: Diff.cpp
Tim doan dai nhat gom cac
phan tu doi mot khac nhau
*/

#include <fstream>
#include <iostream>

using namespace std;

// D A T A A N D V A R I A B L E S

const char * fn = "diff.inp";
const char * gn = "diff.out";
const int mn = 100001;
int p[mn]; // p[v] = i: noi xuat hien so v trong day
int n;
int imax; // chi so dau tien cua doan dai nhat
int dmax; // so phan tu cua doan dai nhat

// P R O T O T Y P E S

int main();
void Run();

// I M P L E M E N T A T I O N

int main() {
Run();
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

void Run() {
int i, j, v, istart;
imax = 0, dmax = 0;
memset(p,0,sizeof(p));
ifstream f(fn);
f >> n;
f >> v; // v phan tu dau day
p[v] = 1; istart = 1;
for (i = 2; i <= n; ++i) {
f >> v;
if (p[v] >= istart) { // so v co trong doan istart..i
if (i-istart > dmax) {
dmax = i-istart; imax = istart;
}
istart = p[v]+1;
}
p[v] = i;
}
f.close();
i = n+1;
if (i-istart > dmax) {
dmax = i-istart; imax = istart;
}
ofstream g(gn); g << imax << endl << dmax;
}

Hon v 1k
Cho dy a gm n s nguyn dng i mt khc nhau. Hy tm on di nht gm cc phn t to thnh
mt hon v ca dy (1, 2 ,..., k), 1 s n, a
i
s 100000.
D liu vo: Tp vn bn hv1k.inp
- Dng u tin: s n.
- T dng th hai tr i: dy s a.
D liu ra: Tp vn bn hv1k.out cha 2 s:
- imax ch s u tin ca on di nht tm c trong dy a
- dmax s phn t ca on di nht.
Cc s trn cng dng cch nhau qua du cch.

hv1k.inp hv1k.out
Gii thch
10
5 2 4 1 5
3 2 6 9 8
3
6
Tnh t phn t th 3 c 6 s
lin tip to thnh mt hon v
ca 1..6 l
4 1 5 3 2 6

Thut ton
K hiu a[i..j] l on gm cc phn t lin tip t a
i
n a
j
ca dy a v k hiu set(x) l tp cha cc phn
t (khc nhau) ca dy x. Vi th d cho ta c, a[1..5] = (5, 2, 4, 1, 5) v do set(a[1..5]) = {1, 2, 4,
5}. Gi p l dy v tr (tr ngc) ca dy a. V dy a gm cc phn t i mt khc nhau nn p cng cha
cc ch s i mt khc nhau. Khi a cha mt on l hon v ca k s t nhin u tin (1,2,...,k) khi v
ch khi tm c hai ch s s v e tha ng thi hai tnh cht sau:
- es+1 = k, v
- set(a[s..e]) = {1, 2, ... , k}.
Trong th d trn ta tm c s = 3, e = 8, k = 6, a[3..8] = (4, 1, 5, 3, 2, 6), v do set(a[3..8]) = {1, 2, 3, 4,
5, 6}.
Xt dy ch s 1, 2, ..., i tha tnh cht j: 1 s j s i: p[j] 0.
rng iu kin p[j] 0 tng ng vi iu kin gi tr j ca dy a xut hin ti v tr p[j]. t s =
min p[1..i] = min {p[1], p[2], ... , p[i]} v e = max p[1..i] = max {p[1], p[2], ... , p[i]}. Ta thy a cha mt
on l hon v ca dy (1,2,...,i) khi v ch khi es+1 = i.
phc tp
O(n).
Chng trnh Pascal
(* --------------------------------------
hv1k.pas
Tim doan dai nhat trong day so
doi mot khac nhau tao thanh mot
hoan vi 1..k
-----------------------------------------*)

const fn = 'hv1k.inp'; gn = 'hv1k.out';
mn = 1000002; nl = #13#10; bl = #32;
var p: array[0..mn] of longint;
n: longint;
imax, dmax: longint;
f,g: text;

procedure Doc;
var i, v: longint;
begin
assign(f,fn); reset(f);
fillchar(p,sizeof(p),0);
readln(f,n);
for i := 1 to n do
begin
read(f,v); p[v] := i;
end;
close(f);
end;

function Min(a,b: longint): longint;
begin
if (a <= b) then Min := a else Min := b
end;

function Max(a,b: longint): longint;
begin
if (a >= b) then Max := a else Max := b
end;

procedure Hv;
var i, pmin, pmax: longint;
begin
pmin := n+1; pmax := 0;
imax := 0; dmax := 0;
for i := 1 to n do
begin
if (p[i] = 0) then break;
pmin := Min(pmin,p[i]);
pmax := Max(pmax,p[i]);
if (pmax - pmin + 1 = i) then
begin
imax := pmin;
dmax := pmax - pmin + 1;
end;
end;
end;

procedure Ghi;
begin
assign(g,gn); rewrite(g);
writeln(g, imax,nl,dmax);
close(g);
end;

procedure Run;
begin
Doc; Hv; Ghi;
end;

BEGIN
Run;
write(nl,' Fini '); readln;
END.

Chng trnh CPP
/* --------------------------------------
devCPP: hv1k.cpp
Tim doan dai nhat trong day so
doi mot khac nhau tao thanh mot
hoan vi 1..k
-----------------------------------------*/
#include <fstream>
#include <iostream>

using namespace std;

// D A T A A N D V A R I A B L E S

const char * fn = "hv1k.inp";
const char * gn = "hv1k.out";
const int mn = 100002;
int p[mn];
int n;
int imax, dmax;

// P R O T O T Y P E S

int main();
void Doc();
int Min(int, int);
int Max(int, int);
void Hv();
void Ghi();
void Run();

// I M P L E M E N T A T I O N

int main() {
Run();
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

void Doc() {
int i, v;
ifstream f(fn);
memset(p,0,sizeof(p));
f >> n;
for (i = 1; i <= n; ++i) {
f >> v;
p[v] = i;
}
f.close();
}

int Min(int a, int b) { return (a <= b) ? a : b; }

int Max(int a, int b) { return (a >= b) ? a : b; }

void Hv() {
int i, pmin = n+1, pmax = 0;
imax = 0; dmax = 0;
for (i = 1; i <= n; ++i) {
if (p[i] == 0) break;
pmin = Min(pmin,p[i]);
pmax = Max(pmax,p[i]);
if (pmax - pmin + 1 == i) {
imax = pmin;
dmax = pmax - pmin + 1;
}
}
}
void Ghi() {
ofstream g(gn);
g << imax << endl << dmax;
g.close();
}

void Run() {
Doc();
Hv();
Ghi();
}

Hon v sk
Cho dy a gm n s nguyn dng i mt khc nhau. Hy tm on di nht gm cc phn t to thnh
mt hon v ca dy s t nhin lin tip (s, s+1 ,..., k), 1 s n, a
i
s 100000.
D liu vo: Tp vn bn hvsk.inp
- Dng u tin: s n.
- T dng th hai tr i: dy s a.
D liu ra: Tp vn bn hvsk.out cha 2 s:
- imax ch s u tin ca on di nht tm c trong dy a
- dmax s phn t ca on di nht.
Cc s trn cng dng cch nhau qua du cch.

hvsk.inp hvsk.out
Gii thch
7
12 1 4 7 8
5 6
3
5
Tnh t phn t th 3 trong dy
a c 5 s lin tip to thnh mt
hon v ca 4..8 l a[3..7]:
4 7 8 5 6

Thut ton
Gi p l dy tr ngc ca dy a. V dy a gm cc phn t i mt khc nhau nn p cng cha cc ch s
i mt khc nhau. Khi a cha mt on l hon v ca dy s t nhin lin tip s..k khi v ch khi tm
c hai ch s i v j tha ng thi hai tnh cht sau:
- ji = ks, v
- set(a[i..j]) = {s, s+1, ... , k}.
Trong th d trn ta tm c i = 3, j = 7, s = 4, k = 8, a[3..7] = (4, 7, 8, 5, 6), v do set(a[3..7]) = {4, 5,
6, 7, 8}.
Khi c d liu ta ng thi xc nh hai gi tr cn vmin v vmax ca dy a. rng p[vmin..vmax]
gm cc on ton 0 v on khc 0 an xen nhau. Th d trn cho ta

a
i

1 2 3 4 5 6 7 8 9 10 11 12
p
2 0 0 3 6 7 4 5 0 0 0 1
vmin = 1. vmax = 12

Khi duyt p[vmin..vmax] ta xt 2 trng thi 0 v 1 nh sau:
Trng thi 0: Duyt on p ton 0, p[2..3] v p[9..11].
Nu gp p[i] > 0 th khi tr cho trng thi duyt on khc 0, p[istart..]:
- Ghi nhn ch s u on khc 0: istart = i,
- Khi tr cac gi tr pmin = min p[istart..k1] v pmax = max p[istart..k1] cho on ny: pmin =
pmax = p[i],
- Chuyn qua trng thi 1.
Trng thi 1: Duyt on p khc 0, p[1..1], p[4..8] v p[12..12].
Nu p[i] > 0 th cp nht cc ch s pmin v pmax. Kim tra ng thc pmaxpmin = iistart cp nht
ch s u tin ca on hon v trong dy a, imax v chiu di ca on hon v, dmax.
Nu p[i] = 0 th kt thc vic duyt on p[isstart..i1] ny, chuyn qua trng thi 0.
phc tp
O(n).
Chng trnh Pascal

Chng trnh CPP
/* --------------------------------------
hvsk.cpp
Tim doan dai nhat trong day so
doi mot khac nhau tao thanh mot
hoan vi cua day so tu nhien lien tiep
s, s+1,...,k
-----------------------------------------*/
#include <fstream>
#include <iostream>

using namespace std;

// D A T A A N D V A R I A B L E S

const char * fn = "hvsk.inp";
const char * gn = "hvsk.out";
const int mn = 100002;
int p[mn];
int pmin, pmax;
int vmin, vmax;
int n;
int imax, dmax;

// P R O T O T Y P E S

int main();
void Doc();
int Min(int, int);
int Max(int, int);
void Hv(); // Sliding window
void Ghi();
void Run();

// I M P L E M E N T A T I O N

int main() {
Run();
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

void Doc() {
int i, v;
ifstream f(fn);
memset(p,0,sizeof(p));
vmin = mn; vmax = 0;
f >> n;
for (i = 1; i <= n; ++i) {
f >> v;
p[v] = i;
vmin = Min(vmin,v); vmax = Max(vmax,v);
}
f.close();
}

int Min(int a, int b) { return (a <= b) ? a : b; }

int Max(int a, int b) { return (a >= b) ? a : b; }

void Hv() {
int i, istart, q = 0; // trang thai q
dmax = 0; ++vmax;
for (i = vmin; i <= vmax; ++i) {
switch(q) {
case 0: // duyet doan toan 0
if (p[i] > 0) { // Khoi tri khi gap so khac 0
pmin = pmax = p[i];
istart = i; q = 1;
}
break;
case 1: // duyet doan khac 0
if (p[i] > 0) {
pmin = Min(pmin,p[i]);
pmax = Max(pmax,p[i]);
if (pmax-pmin == i-istart && pmax-pmin+1 > dmax){
dmax = pmax-pmin+1;
imax = pmin;
}
}
else q = 0;
break;
} // end switch
} // end for
}

void Ghi() {
ofstream g(gn);
g << imax << endl << dmax;
g.close();
}

void Run() {
Doc();
Hv();
Ghi();
}

Hon v 1k di nht
IOIcamp Marathon 2005-2006
Cho dy a gm n s nguyn dng. Hy tm on di nht gm cc phn t to thnh mt hon v ca dy
s t nhin 1..k; 1 s n, a
i
s 100000.
D liu vo: Tp vn bn hv1kmax.inp
- Dng u tin: s n.
- T dng th hai tr i: dy s a.
D liu ra: Tp vn bn hv1kmax.out cha 2 s:
- imax ch s u tin ca on di nht tm c trong dy a
- dmax s phn t ca on di nht.
Cc s trn cng dng cch nhau qua du cch.


hv1kmax.inp hv1kmax.out
Gii thch
10
12 1 4 1 5
3 2 3 1 2
3
5
Tnh t phn t th 3 trong dy
a c 5 s lin tip to thnh mt
hon v ca 1..5 l a[3..7]:
4 1 5 3 2


Thut ton
Duyt dy, da theo bi diff, xc nh tng on ng vin a[d..c] cha ti a cc phn t lin tip nhau
trong dy a v i mt khc nhau. Vi mi on ng vin, da theo bi Hv1k, gi th tc Hv(d,c) xc nh
v cp nht on di nht trong a[d..c] to thnh mt hon v ca dy s t nhin 1..k.
phc tp
Chng trnh Pascal
(* hv1kmax.pas: Tim doan dai nhat gom cac
phan tu tao thanh mot hoan vi cua 1..k *)

const fn = 'hv1kmax.inp'; gn = 'hv1kmax.out';
mn = 100002; bl = #32; nl = #13#10;

var p: array[0..mn] of longint;
{ p[v] - noi xuat hien gia tri v trong day }
n: longint;
imax, dmax: longint;
f, g: text;

function Min(a,b: longint): longint;
begin if (a <= b) then Min := a else Min := b; end;

function Max(a,b: longint): longint;
begin if (a >= b) then Max := a else Max := b; end;

procedure Hv(d,c: longint);
var i, pmin, pmax: longint;
begin
pmin := c+1; pmax := d-1;
for i := 1 to c-d+1 do
begin
if (p[i] < d ) or (p[i] > c) then break;
pmin := Min(pmin,p[i]);
pmax := Max(pmax,p[i]);
if (i > dmax) then
begin
if (pmax - pmin + 1 = i) then
begin
imax := pmin;
dmax := i;
end
end
end;
end;

procedure Ghi;
begin
assign(g,gn); rewrite(g);
writeln(g,imax, nl, dmax); close(g);
end;

procedure Run;
var i, v , istart: longint;
begin
fillchar(p,sizeof(p),0);
imax := 0; dmax := 0;
assign(f,fn); reset(f);
readln(f,n);
read(f,v); { v phan tu dau day a }
p[v] := 1; istart := 1; { chi so dau doan }
for i := 2 to n do
begin
read(f,v);
if (p[v] >= istart) then { gap phan tu trung lap }
begin
if (i-istart > dmax) then Hv(istart, i-1);
istart := p[v]+1; { Khoi tri dau doan moi }
end;
p[v] := i;
end;
close(f);
if (n+1-istart > dmax) then Hv(istart,n);
Ghi;
end;

BEGIN
Run;
write(nl,' Fini '); readln;
END.

Chng trnh CPP

/* DevC++: hv1kmax.cpp
Tim doan dai nhat gom cac
phan tu tao thanh mot hoan vi cua 1..k
*/
#include <fstream>
#include <iostream>

using namespace std;

// D A T A A N D V A R I A B L E S

const char * fn = "hv1kmax.inp";
const char * gn = "hv1kmax.out";
const int mn = 100002;
int p[mn]; // p[v] - noi xuat hien gia tri v trong day
int n;
int imax, dmax;

// P R O T O T Y P E S

int main();
void Run();
int Min(int, int);
int Max(int, int);
void Hv(int, int); // Sliding window
void Ghi();

// I M P L E M E N T A T I O N

int main() {
Run();
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

int Min(int a, int b) { return (a <= b) ? a : b; }

int Max(int a, int b) { return (a >= b) ? a : b; }

// tim hoan vi 1..n trong doan
// gom cac phan tu khac nhau doi mot
void Hv(int d, int c) {
int i, pmin = c+1, pmax = d-1;
int n = c-d+1;
for (i = 1; i <= n; ++i) {
if (p[i] < d || p[i] > c) break;
pmin = Min(pmin,p[i]);
pmax = Max(pmax,p[i]);
if (i > dmax) {
if (pmax - pmin + 1 == i) {
imax = pmin;
dmax = i;
}
}
}
}

void Ghi() {
ofstream g(gn);
g << imax << endl << dmax;
g.close();
}

void Run() {
int i, v , istart;
memset(p,0,sizeof(p));
imax = 0; dmax = 0;
ifstream f(fn);
f >> n;
f >> v; p[v] = 1; istart = 1;
for (i = 2; i <= n; ++i) {
f >> v;
if (p[v] >= istart) {
if (i-istart > dmax) Hv(istart, i-1);
istart = p[v]+1;
}
p[v] = i;
}
f.close();
if (n+1-istart > dmax) Hv(istart,n);
Ghi();
}
Hon v sk di nht
Cho dy a gm n s nguyn dng. Hy tm on di nht gm cc phn t to thnh mt hon v ca dy
s nguyn dng lin tip s, s+1,...,k; 1 s n, a
i
s 100000.
D liu vo: Tp vn bn hvskmax.inp
- Dng u tin: s n.
- T dng th hai tr i: dy s a.
D liu ra: Tp vn bn hvskmax.out cha 2 s:
- imax ch s u tin ca on di nht tm c trong dy a
- dmax s phn t ca on di nht.
Cc s trn cng dng cch nhau qua du cch.


hvskmax.inp hvskmax.out
Gii thch
10
5 1 9 7 5
8 6 3 9 2
3
5
Tnh t phn t th 3 trong dy
a c 5 s lin tip to thnh mt
hon v ca 5..9 l a[3..7]:
9 7 5 8 6

Thut ton
Pha 1. c dy a, vi mi a
i
ghi nhn p[a
i
] = i l v tr xut hin gi tr a
i
. Gi vmin v vmax ln lt l gi
tr min v max ca dy a.
Pha 2. Dut dy gi tr i = vmin..vmax to thnh mt on d gm cc gi tr xut hin lin tip trong dy
a, xc nh cc gi tr pmin v pmax l v tr xut hin u tin v cui cng trong on d. on d l mt
hon v ca dy s nguyn dng lin tip i, i+1,...,s khi v ch khi pmaxpmin+1 = si.
phc tp
Chng trnh Pascal
Chng trnh CPP

/* DevC++: hv1kmax.cpp
Tim doan dai nhat gom cac
phan tu tao thanh mot hoan vi cua s..k
*/
#include <fstream>
#include <iostream>

using namespace std;

// D A T A A N D V A R I A B L E S

const char * fn = "hvskmax.inp";
const char * gn = "hvskmax.out";
const int mn = 100002;
int p[mn]; // p[v] - noi xuat hien gia tri v trong day
int a[mn];
int n;
int imax, dmax;

// P R O T O T Y P E S

int main();
void Run();
int Min(int, int);
int Max(int, int);
void Hv(int, int); // Sliding window
void Ghi();

// I M P L E M E N T A T I O N

int main() {
Run();
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

int Min(int a, int b) { return (a <= b) ? a : b; }

int Max(int a, int b) { return (a >= b) ? a : b; }

void Hv(int d, int c) {
int i, istart, q = 0, pmin = c+1, pmax = d-1;
int vmin, vmax;
// trang thai q
vmin = vmax = a[d];
for (i = d+1; i <= c; ++i) {
vmin = min(vmin,a[i]);
vmax = max(vmax,a[i]);
}
for (i = vmin; i <= vmax; ++i) {
switch(q) {
case 0: // duyet doan toan 0
if (p[i] > 0) { // Khoi tri khi gap so khac 0
pmin = pmax = p[i];
istart = i; q = 1;
}
break;
case 1: // duyet doan khac 0
if (p[i] > 0) {
pmin = Min(pmin,p[i]);
pmax = Max(pmax,p[i]);
if (pmax-pmin == i-istart && pmax-pmin+1 > dmax){
dmax = pmax-pmin+1;
imax = pmin;
}
}
else q = 0;
break;
} // end switch
} // end for
}

void Ghi() {
ofstream g(gn);
g << imax << endl << dmax;
g.close();
}

void Run() {
int i, v , istart;
memset(p,0,sizeof(p));
imax = 0; dmax = 0;
ifstream f(fn);
f >> n;
f >> v; a[1] = v; p[v] = 1; istart = 1;
for (i = 2; i <= n; ++i) {
f >> v; a[i] = v;
if (p[v] >= istart) {
if (i-istart > dmax) Hv(istart, i-1);
istart = p[v]+1;
}
p[v] = i;
}
f.close();
if (n+1-istart > dmax) Hv(istart,n);
Ghi();
}

on nguyn t
Cho n s t nhin a
i
i = 1..n. Hy tm on di nht gm cc phn t l cc s nguyn t.
1 s n, a
i
s 100000.
/* ---------------------------------------
Primes.cpp
Tim doan dai nhat gom cac so nguyen to
----------------------------------------*/
#include <fstream>
#include <iostream>
#include <math.h>

using namespace std;

// D A T A A N D V A R I A B L E S

const int mn = 100001;
const char * fn = "primes.inp";
char p[mn]; // p[i] = 0=> i nguyen to
int n;
int imax, dmax;

// P R O T O T Y P E S
void Run();
void Sang(int);
void Duyet();

// I M P L E M E N T A T I O N
int main() {
Run();
cout << endl << " Fini ";
cin.get();
return 0;
}

void Sang(int n) {
int can = (int) sqrt(n);
int i, j, k;
p[0] = p[1] = 1;
for (i = 2; i <= can; ++i)
if (p[i]==0)
for (k = n/i, j = i; j <= k; ++j) p[i*j] = 1;
}

void Duyet() {
int i, x, d;
imax = 0; dmax = 0; d = 0;
ifstream f(fn);
f >> n;
for (i = 1; i <= n; ++i) {
f >> x; cout << x << " ";
if (p[x]) { // x khong nguyen to
if (d > dmax) {
dmax = d; imax = i;
}
d = 0;
} else ++d;
}
f.close();
if (d > dmax) {
dmax = d; imax = n+1;
}
imax = imax - dmax;
}

void Run() {
Sang(mn);
Duyet();
cout << endl << imax << " " << dmax;
}

on nguyn t cng nhau
Cho n s t nhin a
i
i = 1..n. Hy tm on di nht gm cc phn t, trong hai phn t k nhau th
nguyn t cng nhau.
1 s n, a
i
s 100000.

/* ---------------------------------------
Primes.cpp
Tim doan dai nhat gom cac so nguyen to
cung nhau
----------------------------------------*/
#include <fstream>
#include <iostream>
#include <math.h>

using namespace std;

// D A T A A N D V A R I A B L E S

const int mn = 100001;
const char * fn = "coprime.inp";
char p[mn]; // p[i] = 0=> i nguyen to
int n;
int imax, dmax;

// P R O T O T Y P E S
void Run();
void Duyet();
int Gcd(int, int);

// I M P L E M E N T A T I O N
int main() {
Run();
cout << endl << " Fini ";
cin.get();
return 0;
}

int Gcd(int a, int b) {
int r;
while (b) {
r = a % b; a = b; b = r;
}
return a;
}

void Duyet() {
int i, x, y, d; // d dem so cap nguyen to cung nhau
imax = 0; dmax = 0; d = 0;
ifstream f(fn);
f >> n >> x;
for (i = 2; i <= n; ++i) {
f >> y;
if (Gcd(x,y) == 1) ++d;
else {
if (d > dmax) {
dmax = d; imax = i;
}
d = 0;
}
x = y;
}
f.close();
if (d > dmax) {
dmax = d; imax = n;
}
++dmax; imax = imax - dmax;
}

void Run() {
Duyet();
cout << endl << imax << " " << dmax;
}

Bi ton Euler N 28
Trong ma trn vung n X n, n l xut pht t gia ghi ln lt cc s t 1..n
2
theo ng xon c theo
chiu kim dng h. Vi n = 5 tng cc phn t trn 2 ng cho l 101. Hy tnh tng ny vi n = 1001.


21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13


Nhn xt
Xt cc s nm bn gc ca hnh vun cnh n. S gc trn phi l n
2
, cc s cn li
ln lt l n
2
(n1), n
2
2(n1) v n
2
3(n1). Tng 4 s ny l
d(n) = n
2
+ n
2
(n1) + n
2
2(n1) + n
2
3(n1) = 4n
2
6(n1), n > 1
Vi n = 1, d(1) = 1.
Tng cc s trn hai ng cho chnh l
s(n) = d(1) + d(3) ++d(n).

/*
Name: Problem Euler 28
Copyright: NXH 2010
Author: Nguyen Xuan Huy
Date: 10/06/10 10:53
Description:
2 mau (den, trang) va 16 mau
*/

#include <iostream>
#include <stdio.h>

using namespace std;

int Euler28(int n) {
int e = 1;
for (int i = 3; i <= n; i += 2)
e += 4*i*i - 6*(i-1);
return e;
}

main() {
cout << endl << Euler28(1001); // 669171001
cout << endl << " Fini";
cin.get();return 0 ;
}

Bi ton Euler N 52
S x = 125874, v 2x = 251748 c to bi cng ch s theo trt t khc nhau. Tm s t nhin nh nht
x sao cho 2x, 3x, 4x, 5x v 6x c cc ch s ddoooi mt khc nhau v l nhng hon v ca x. (142857)
C trn 5 s tha tnh cht trn hay ko?
Nu ko i hi cc ch s khc nhau?
Vi cc s nguyn dng 1..4294967295 (2
32
1) c 10 s
1. : 142857
2. : 1428570
3. : 1429857
4. : 14285700
5. : 14298570
6. : 14299857
7. : 142857000
8. : 142985700
9. : 142998570
10. : 142999857

Chng trnh tnh v ghi file 10 s

/*
Name: Problem Euler 28
Copyright: NXH 2010
Author: Nguyen Xuan Huy
Date: 10/06/10 10:53
Description:
2 mau (den, trang) va 16 mau
*/

#include <iostream>
#include <fstream>

typedef uint32_t UI;

const UI maxint = (UI)0xffffffff;

using namespace std;

char digits[10];
char mark[10];

void GetDigits(UI x, char dg[]) {
for (int i = 0; i < 10; ++i) dg[i] = 0;
do {
++dg[x%10];
x /= 10;
} while (x);
}

bool SameDigits(UI x) {
GetDigits(x,mark);
for (int i = 0; i < 10; ++i)
if (digits[i] != mark[i]) return false;
return true;
}

bool Test(UI x) {
GetDigits(x,digits);
UI d = x;
x += d; // 2x
for (int i = 2; i <= 6; ++i, x += d) {
if (!SameDigits(x)) return false;
}
return true;
}

UI Euler52(UI n) {
bool b;
for (UI x = n+1; x <= maxint; ++x)
if (Test(x)) return x;
return 0;
}

int Euler52m() { // co tren 10 so Euler52?
int d;
UI x = 0;
ofstream f("Euler52.txt");

for (d = 0; (x = Euler52(x)) > 0;) {
++d;
f << endl << d << ". : " << x;
// if (d == 10) break;
}
f.close();
return d;
}

main() {

int d = Euler52m();
cout << "\n\n Found: " << d;
cout << endl << " Fini";
cin.get();return 0 ;
}

Cc s nguyn t

Tm c 340059 s, s cui l 4870843 vi lp n < 500.
tng: nu p[1..n] , c = p[n] l danh sch n s nguyn t u tin v x l mt s l trong khong c..c*c th
x l nguyn t khi v ch khi x khng c c nguyn t trong khong 3.. x .
Xut pht p = (2,3) 2 s nguyn t u tin. n = 2 l s lng cc s nguyn t hin tm c.
Find: xt cc s l x trong khong t p
n
+ 2 n p
n
2
2. Ch , do p
n
l s l nn p
n
2

l. Nu x l ng t th
thm vo dy.
kim tra tnh ng t ca x


/*
Name: Problem Euler 28
Copyright: NXH 2010
Author: Nguyen Xuan Huy
Date: 10/06/10 10:53
Description:
2 mau (den, trang) va 16 mau
*/

#include <iostream>
#include <math.h>

typedef uint32_t UI;

const UI maxn = 20000000;

using namespace std;

UI p[maxn];
UI n;

bool IsPrime(UI x) {
UI can = (UI) sqrt(x);
for (UI i = 2; p[i] <= can; ++i)
if (x % p[i] == 0) return false;
return true;
}

// Tim tu n
void Find() {
UI n2 = p[n]*p[n] - 2;
for (UI i = p[n] + 2; i <= n2; i += 2)
if (IsPrime(i)) p[++n] = i;
}


void Run() {
p[1] = 2; p[2] = 3;
n = 2;
while (n < 500) {
cout << endl << " Find with n = " << n;
Find();
cout << endl << " Tong cong " << n << " so nguyen to ";
cout << endl << " So nguyen to lon nhat: " << p[n];
cin.get();
}
}

main() {
Run();
cout << endl << " Fini";
cin.get();
return 0 ;
}

Problem Euler 1
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and
9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.

/*
Name: Problem Euler 01
Copyright: NXH 2010
Author: Nguyen Xuan Huy
Date: 10/06/10 10:53
Description:
If we list all the natural numbers below 10 that are multiples
of 3 or 5,
we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.

*/

#include <iostream>
#include <stdio.h>

const int mn = 1001;

using namespace std;

inline int Min(int a, int b) { return (a <= b) ? a : b; }

int Euler01(int maxval) {
int a[mn];
int n;
int i3 = 0, i5 = 0;
int s = 0;
n = 0;
a[0] = 1;
while (a[n] < maxval) {
while (3*a[i3] <= a[n]) ++i3;
// 3*a[i3] > a[n]
while (5*a[i5] <= a[n]) ++i5;
// 5*a[i5] > a[n]
a[++n] = Min(3*a[i3],5*a[i5]);
}
if (a[n] > maxval) --n;
for (int i = 1; i <= n; ++i) s += a[i];
return s;
}

main() {

cout << endl << Euler01(1000); // 3822
cout << endl << " Fini";
cin.get();
return 0 ;
}


Each new term in the Fibonacci sequence is generated by adding the previous two terms.
By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
Find the sum of all the even-valued terms in the sequence which do not exceed four
million.
Thut ton
Ta c f
1
= 1; f
2
= 2 l s chn u tin. V tng l + l = chn v l + chn = chn + l =
l, nn su 2 s l ta mi gp 1 s chn. T suy ra cc f
i
vi i = 2 + 3k, k = 0, 1, l
cc s chn. ca s chn. Gi f
i
l s chn, ta c:
f
i1
l s l st trc f
i
.
f
i+1
= f
i1
+ f
i
(l),
f
i+2
= f
i
+ f
i+1
= f
i
+ f
i1
+ f
i
= 2f
i
+ f
i1
(l),
f
i+3
= f
i+1
+ f
i+2
= f
i1
+ f
i
+ 2f
i
+ f
i1
= 3f
i
+ 2f
i1
= 2f
i+2
f
i
(chn)
Ta s dng bin odd lu s l v bin even lu s chn st sau odd. Ta c,
Khi tr: odd = 1; even = 2;
Bc tip theo: odd = 2*even + odd; even = 2*odd even;


/*
Name: Problem Euler 02
Copyright: NXH 2010
Author: Nguyen Xuan Huy
Date: 10/06/10 10:53
Description:
Each new term in the Fibonacci sequence is generated by adding
the previous two terms. By starting with 1 and 2, the first 10
terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...


Find the sum of all the even-valued terms in the sequence
which do not exceed four million.

*/

#include <iostream>
#include <stdio.h>

using namespace std;

int Euler02(int maxval) {
int odd = 1, even = 2;
int s = even;
while (even < maxval) {
odd = 2*even + odd;
even = 2*odd - even;
s += even;
}
if (even > maxval) s -= even;
return s;
}

main() {
cout << endl << Euler02(4000000); // 4613732
cout << endl << " Fini";
cin.get();
return 0 ;
}

Euler03
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?



Khi tr vi danh sch cha k = 2 s nguyn t p[1] = 2; p[2] = 3. Hm NextPrime(k) tm s nguyn t st
sau s nguyn t p[k]. Gi hm NextPrime nhiu ln n khi thu c s nguyn t p[k] > n . DuThe
prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ? (6857)

/*
Name: Euler03
Copyright: NXH 2010
Author: Nguyen Xuan Huy
Date: 10/06/10 10:53
Description:
The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number
600851475143 ?
*/

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <time.h>

using namespace std;

typedef long double BI; // kieu gia nguyen

BI p[100000];
BI x = 600851475143.0;

// Test if y is a prime number

bool IsPrime(BI y) {
BI ys = floorl(sqrt(y));
for (int i = 1; p[i] <= ys; ++i)
if (fmodl(y,p[i]) == 0.0) return false;
return true;
}

// Given a list consequenced first k prime numbers
// p[1..k] = (3,5,7,..p[k]), k > 1.
// Find the next prime number (after p[k])

inline BI NextPrime(int k) {
BI n;
for (n = p[k] + 2; !IsPrime(n); n += 2);
return n;
}

// Find the lagest prime factor of a given integer n

BI Euler03(BI n) {
BI sn;
int i, imax, k = 2;
BI m;
// Initialize: p[1..2] = (2,3); k = 2: two first
prime numbers (2 and 3).
p[1] = 2; p[2] = 3;
sn = floorl(sqrt(n));
cout << endl << " n = " << n << " sqrt(n) = " <<
sn;
// Find consequenced prime numbers not greater
than sqrt(n)
while (p[k] < sn) {
m = NextPrime(k);
p[++k] = m;
}
cout << endl << " Found " << k << " prime
number(s). " << endl;
cout << endl << " The last one is : " << p[k];
// Find the last index imax in p[1..k] so p[imax]
is a prime factor of n
imax = 0;
for (i = 1; i <= k; ++i)
if (fmodl(n,p[i]) == 0.0) {
imax = i;
do { n /= p[i]; } while (fmodl(n,p[i]) ==
0.0);
}
cout << "\n Now n = " << n << " imax = " <<
imax;
cout << " pmax = " << p[imax] << endl;

// if imax = 0: n did not have any prime factors
in p[1..k]
// so n is a prime number. We return n
if (imax == 0) return n; // n is a prime number

return (n < p[imax]) ? p[imax] : n;

}

main() {
time_t t1,t2;
t1 = time(NULL);
BI r = Euler03(x); // 6857
t2 = time(NULL);
float d = difftime(t2,t1);// sec.
cout << endl << " Time: " << d << " sec. " << endl;
cout << "\n\n The result: " << r;
cout << endl << " Fini";
cin.get();
return 0;

}

Euler04
A palindromic number reads the same both ways. The largest palindrome made from the
product of two 2-digit numbers is 9009 = 91 99.
Find the largest palindrome made from the product of two 3-digit numbers.
/*
Name: Problem Euler 04
Copyright: NXH 2010
Author: Nguyen Xuan Huy
Date: 10/06/10 10:53
Description:
Euler04
A palindromic number reads the same both ways. The
largest palindrome made from the product of two 2-
digit numbers is 9009 = 91 99.
Find the largest palindrome made from the product of
two 3-digit numbers.

*/

#include <iostream>
#include <stdio.h>;


using namespace std;

int Exp(int a, int x) {
int z = 1;
while (x) {
if (x % 2 == 1) z *= a;
a = a * a;
x /= 2;
}
return z;
}

int Rev(int z) {
int x = 0;
while(z) {
x = x * 10 + (z % 10);
z /= 10;
}
return x;
}

void Euler04(int digitNumber, int & x, int & y) {
int maxNum = Exp(10,digitNumber) - 1;
int z;
for (x = maxNum; x >= 0; --x)
for (y = maxNum; y >= 0; --y){
z = x*y;
if (z == Rev(z)) return;
}
}

main() {
int x, y;
Euler04(3,x,y);
cout << endl << x << " * " << y << " = " << (x * y);
// x = 999, y = 91, x*y = 90909
cout << endl << " Fini";
cin.get();
return 0 ;
}


1. 9 * 1 = 9
2. 99 * 91 = 9009
3. 995 * 583 = 580085
4. 9999 * 9901 = 99000099
Euler69
Euler's Totient function, (n) [sometimes called the phi function], is used to determine the number of
numbers less than n which are relatively prime to n. For example, as 1, 2, 4, 5, 7, and 8, are all less than
nine and relatively prime to nine, (9)=6.
n Relatively Prime (n) n/(n)
2 1 1 2
3 1,2 2 1.5
4 1,3 2 2
5 1,2,3,4 4 1.25
6 1,5 2 3
7 1,2,3,4,5,6 6 1.1666...
8 1,3,5,7 4 2
9 1,2,4,5,7,8 6 1.5
10 1,3,7,9 4 2.5
It can be seen that n = 6 produces a maximum n/(n) for n 10.
Find the value of n 1,000,000 for which n/(n) is a maximum.
n = 100000 (mt trm ngn); max phi(i)/i = 5.21354 t ti i = 30030; 1 sec.
n = 1000000 (mt triu) ; max phi(i)/i = 5.53939 t ti i = 510510 di 1 sec.
Nhn xt 1
Nu n = p
1
m
1
p
2
m
2
p
k
m
k
th (n) = p
1
m
1
1
p
2
m
2
1
p
k
m
k
1
.(p
1
1)(p
2
1)(p
k
1).
Do , k hiu E(n) = n/(n), ta c
E(n) = n/(n) = (p
1
p
2
p
k
)/((p
1
1)(p
2
1)(p
k
1)) (*)
K hiu S(n) l tp cc c nguyn t (khc nhau) ca n, th d, n = 60 thf S(n) = { 2, 3, 5 }. Cng thc (*)
cho ta bit, nu hai s t nhin n v m c S(n) = S(m) th E(n) = E(m). Th d, n = 10
i
v m = 10
j
s cho
cng gi tr E v S(n) = S(m) = { 2, 5 }.
Xt dy lin tip cc s nguyn t p
i
2, 3, 5,
V p < q suy ra pqq < pq p hay q(p1) < p(q1) tc q/(q1) < p/(p1). Vy dy p
i
/(p
i
-1) vi i = 1, 2
gim dn: p
i
/(p
i
-1) < p
i+1
/(p
i+1
-1).
Vy tch p
1
/(p
1
-1) * p
2
/(p
2
-1) * * p
k
/(p
k
-1) t max khi tch p
1
p
2
p
k
l s ln nht khng vt qu n.
/*
Name: Problem Euler 02
Copyright: NXH 2010
Author: Nguyen Xuan Huy
Date: 10/06/10 10:53
Description:
It can be seen that n=6 produces a maximum n/phi(n) for n <=
10.
Find the value of n <=1,000,000 for which n/phi(n) is a
maximum.

*/

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <time.h>

using namespace std;

typedef uint32_t UI;

UI p[10];

inline UI Min(UI a, UI b) { return ( a <= b) ? a : b; }

bool IsPrime(UI y) {
UI ys = (UI)(sqrt(y));
for (UI d = 1; p[d] <= ys; ++d)
if (y % p[d] == 0) return false;
return true;
}

inline UI NextPrime(int k) {
for (k = p[k] + 2; !IsPrime(k); k += 2);
return k;
}

float Euler69(UI n, UI & a) {
int k = 2;
UI m;
UI b;
p[1] = 2; p[2] = 3;
a = p[1]*p[2]; b = (p[1]-1)*(p[2]-1);
while (a < n) {
m = NextPrime(k);
p[++k] = m;
a *= m; b *= (m-1);
}
if (a > n) { a /= m; b /= (m-1); --k; }
cout << endl << " Found " << k << " prime numbers " << endl;
for (int i = 1; i <= k; ++i) cout << p[i] << " ";
return (float) a/b;
}

void Test() {
time_t t1,t2;
t1 = time(NULL);
UI n;
float r = Euler69(1000000, n);
cout << endl << " result: n/phi(n) = " << r << " n = " <<
n;
t2 = time(NULL);
float d = difftime(t2,t1);// sec.
cout << endl << " Time: " << d << " sec. " << endl;
}

main() {
Test();
cout << (UI)(2*3*5*7*11*13*17*19);
cout << endl << " Fini";
cin.get();
return 0;
}

Problem 5
30 November 2001

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any
remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?

Problem 6
14 December 2001

The sum of the squares of the first ten natural numbers is,
1
2
+ 2
2
+ ... + 10
2
= 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)
2
= 55
2
= 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the
sum is 3025 385 = 2640.
Find the difference between the sum of the squares of the first one hundred natural numbers and the square
of the sum.
2 phng n.
Phng n 1. Tnh theo 2 vng lp, O(n
2
).
Phng n 2. O(n).
Cc cng thc:

+ =
=
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;
}

You might also like