You are on page 1of 163

T SCH TRI THC DUY TN

NGUYN XUN HUY

SNG TO
TRONG THUT TON
V
LP TRNH
vi ngn ng Pascal v C++
Tp 3

Tuyn cc bi ton Tin nng cao


cho hc sinh v sinh vin gii

MC LC

Li ni u ......................................................................................................................... 4
Chng 1 Cc thut ton trn String................................................................................ 5
1.1 Xu k t ............................................................................................................................... 5
1.2 V t chc d liu vo/ra..................................................................................................... 6
1.3 Data ....................................................................................................................................... 6
1.4 Xu con chung ...................................................................................................................... 8
1.5 on chung ........................................................................................................................... 9
1.6 on lp .............................................................................................................................. 11
1.7 T in ................................................................................................................................ 14
1.8 TEFI .................................................................................................................................... 17
1.9 E xic ................................................................................................................................... 20

Chng 2 X l dy lnh v biu thc ............................................................................ 23


2.1 Val ....................................................................................................................................... 23
2.2 Xu thu gn ........................................................................................................................ 26
2.3 Robot ................................................................................................................................... 29
2.4 Hm nhiu bin .................................................................................................................. 33
2.5 Files ..................................................................................................................................... 38
2.6 Gen ...................................................................................................................................... 44
2.7 Ti u ha chng trnh ................................................................................................... 44
2.8 Mc ca biu thc ............................................................................................................. 45
2.9 Thp .................................................................................................................................... 46
2.10 Mi trang ............................................................................................................................ 46
2.11 Xp th .............................................................................................................................. 49
2.12 Xp xe ................................................................................................................................ 50

Chng 3 Cp ghp ........................................................................................................ 51


3.1 Ch Hng ............................................................................................................................. 51
3.2 Domino ................................................................................................................................ 55
3.3 Thm him .......................................................................................................................... 59
3.4 Show .................................................................................................................................... 64
3.5 Cp ghp cc i: Ch Hng 2 ......................................................................................... 70

Chng 4 Cc php lt v chuyn v............................................................................... 75


4.1 Lt xu ................................................................................................................................ 75
4.2 Lt s nguyn ..................................................................................................................... 76
4.3 Sn bay v tr .................................................................................................................... 77
4.4 Cn ...................................................................................................................................... 81
4.5 Biprime ............................................................................................................................... 87
4.6 Chuyn bi ............................................................................................................................ 90

4.7 Lt nn 2 ............................................................................................................................. 94
4.8 Test .................................................................................................................................... 103
4.9 Gii m .............................................................................................................................. 105

Chng 5 Luyn tp t cc thi ................................................................................. 110


5.1 S nguyn t cng cao ................................................................................................ 110
5.2 S nguyn t cng s bt 1 ............................................................................................... 112
5.3 Ct hnh ............................................................................................................................ 112
5.4 Tng nh nht .................................................................................................................. 115
5.5 L c .................................................................................................................................. 119
5.6 Chuyn tin ........................................................................................................................ 127
5.7 M BW .............................................................................................................................. 130
5.8 Tam gic Pascal ................................................................................................................ 134
5.9 Sn m hnh...................................................................................................................... 138
5.10 Nhng m hnh ............................................................................................................... 141
5.11 S st sau nh phn ........................................................................................................ 144
5.12 Hm f(n) .......................................................................................................................... 150
5.13 Hm h(n) ......................................................................................................................... 151
5.14 Rhythm ........................................................................................................................... 151
5.15 Cc ................................................................................................................................... 152
5.16 Tr tin ........................................................................................................................... 154
5.17 Game ............................................................................................................................... 156
5.18 Robots ............................................................................................................................. 160

Li ni u

Theo yu cu ca bn c, trong tp 3 ny chng ti minh ha bng hai ngn ng lp trnh l Pascal


v Dev-C++. Pascal l ngn ng lp trnh mang tnh s phm cao v c dng ging dy trong nh
trng ph thng theo chng trnh hin hnh. Dev-C++ l mi trng m ngun m c cc bn sinh
vin yu thch v thng c chn lm mi trng lp trnh trong cc cuc ua ti quc gia v quc t.
C hai mi trng Free Pascal v Dev-C++ u c cung cp min ph trn Internet.
Chng ti hy vng rng s tip tc nhn c nhng kin ng gp qu bu ca bn c gn xa v
ni dung v hnh thc trnh by ca b sch.
H Ni, Ma Xun nm Dn 2010
Nguyn Xun Huy

Chng 1 Cc thut ton trn String

1.1 Xu k t
Xu k t l mt dy cc k t vit lin nhau. Cc k t c ly t mt bng ch ci cho trc, thng
thng l bng m ASCII. Trong cc bi ton tin, k t thng c hiu l ch ci vit HOA hoc vit
thng theo trt t b tr trong bng ch ci ting Anh v cc ch s. C th hiu xu k t l mt mng
mt chiu cha cc k t. i lc ta gi vn tt l xu. Hiu theo ngha ny ta c th khai bo xu k t nh
sau:
// Dev-C++
char x[1000];
char *y = new char[1000];
C hai khai bo trn l tng ng nhau v x, y u c dung lng hay sc cha ti 1000 k t vi cc ch
s t 0 n 999. Cc xu k t trong C++ c kt thc bng k t (du) kt xu '\0'. Bn cn chc chn
rng du kt xu lun lun c mt trong cc xu do bn qun l. Mt s hm h thng ca C++ t ng dt
du kt xu vo cui xu k t. Nu bn t vit cc hm x l xu th bn cn c thao tc tng minh t
du kt xu vo cui xu. Nu bn khai bo xu k t x gm 1000 k t nh trn th bn ch c php ghi
vo xu ti a 999 k t (gi l cc k t c ngha). V tr cui cng x[999] phi dnh ghi du kt xu
'\0'.
Trong Pascal vi nhng xu ngn, c chiu di khng qu 255 k, t bn nn s dng kiu string, th d
(* Pas *)
var x: string[100];
Khai bo trn cho php bn s dng xu x nh mt mng gm 101 phn t,
x: array[0..100] of char;
Tuy nhin, bn cn nh rng phn t x[0] c h thng dnh ring ghi chiu di hin hnh ca xu.
Th d,
(* Pascal *)
var x: string[100];
x := 'abc';
s gn x[1] = 'a'; x[2] = 'b'; x[3] = 'c'; Ring x[0] c gn k t c m ASCII
l 3: x[0] = #3.
Nh vy bn c s dng ng 100 k t c ngha.
Chiu di hin hnh khc vi sc cha. Xu x ni trn c sc cha 100 bytes dnh cho bn, khng tnh
byte u tin x[0], cn chiu di hin hnh l 3. Chiu di hin hnh c tnh trong C++ bng hm
strlen, trong Pascal bng hm length.
Vi nhng xu di trn 255 k t bn nn khai bo nh mt mng, th d
(* Pascal *)
var x: array[1..1000] of char;
v x l x nh mt mng.
Trong C++ cng c kiu d liu string dnh ring cho vic qun l cc xu. Vi kiu ny bn c th thc
hin mt s hm tin ch nh cng hai xu x+y, gn tr x = y, Th d,
// Dev-C++
int main(){
string x = "abc", y = x;
cout << endl << x << " + " << y << " = " << (x+y);
// abc + abc = abcabc
cin.get();
return 0;
}
Cc xu trong bi u c hiu thng nht vi ch s tnh t 1 n N. Khi lp trnh bng C++ bn lu
chuyn i kt qu cui cng t ch s i sang i+1. Bn cng c th ghi d liu t ch s 1 tr i, b qua
phn t 0.
Hng xu k t trong C++ c ghi gia hai du nhy kp, th d "string in CPP", trong Pascal c
ghi gia hai du nhy n, th d, 'string in Pascal'. Nu gia hai du nhy n hoc kp ta
khng ghi k t no th ta thu c mt xu rng l xu c chiu di 0.

Cho xu s[1..n]. Mt on ca s l dy lin tip cc k t trong s. Ta k hiu s[d..c] l on ca s tnh t ch


s d n ch s c. Th d, nu s = 'abcdegh' th s[2..5] = 'bcde' l mt on. on s[1..i]
c gi l tin t i ca s v c k hiu l i:s. on s[i..n]
Cc tin t v hu t ca xu s = 'abcd'
c gi l hu t i ca s v c k hiu l s:i. Xu di n k
Tin t
Hu t
t c ng n tin t v n hu t.
Nu xa khi s mt s k t v (tt nhin) dn cc k t cn
li cho k nhau, ta s thu c mt xu con ca s.

1:s = s[1..1] = 'a'

s:1 = s[1..4] = 'abcd'

2:s = s[1..2] = 'ab'

s:2 = s[2..4] = 'bcd'

1.2 V t chc d liu vo/ra

3:s = s[1..3] = 'abc'

s:3 = s[3..4] = 'cd'

Trong hu ht cc bi ta gi thit d liu vo v ra c ghi


4:s = s[1..4] = 'abcd' s:4 = s[4..4] = 'd'
trong cc text file *.INP v *.OUT. Tn v cch thc ghi d
liu trong cc file c cho trong tng th d c th ca mi
bi. Theo gi thit ny trong cc bi gii s ch tp trung gii thiu nhng thut ton c bn, cc bn s t
vit phn t chc vo/ra thu c chng trnh hon chnh.
Turbo Pascal v Borland C++ b hn ch v min nh. Cc bn nn s dng Free Pascal v DevC++ c
th cp pht nhng mng d liu ln vi hng t bytes. Cc mng trong C++ c gn ch s 0, cn
trong Pascal ch s mng do ngi lp trnh t t. Trong DevC++, nu f l input file dng text th dng
lnh f >> x c d liu vo i tng x n khi gp du cch. Mun c y mt dng d liu cha
c du cch t input file f vo mt bin mng k t s ta c th dng phng thc getline nh th d sau y
char s[1001];
f.getline(s,1000,'\n');
Phng thc ny c mt dng ti a 1000 k t vo bin s, v thay du kt dng '\n' trong input file bng
du kt xu '/0' trong C.
Lnh memset(a,0,sizeof(a)) gn ton 0 cho mi byte ca mng a.
Lnh memmove(a,b,n) copy n byte t mng b sang mng a.
Lnh strcpy(x,"abcd"); khi tr "abcd" cho xu x
lm quen vi cc thao tc c/ghi d liu bn hy th gii bi ton di y.

1.3 Data

data.inp
Tinh tong cua 12 so sau day:
1 -2 3 -4 5 6
7 8 9 10 -11 -12
data.out
Tong cua 12 so:
+1 -2 +3 -4 +5 +6 +7 +8 +9 +10 -11 -12 = 20

Trong file vn bn data.inp cha


dng d liu u tin c ni dung
"Tinh tong cua n so sau day:",
trong n l mt s nguyn dng
cho trc.
Tip n l n s nguyn ghi cch
nhau qua du cch.
Yu cu: xc nh gi tr ca n v tnh tng ca n s trong file data.inp ri ghi kt qu vo output file
data.out theo nh dng cho trong bng.
Thut ton
Ta vit th tc Tong theo cc bc:
1. M input file f tn "data.inp".
2. Cp pht bin string s, c dng u tin vo s.
3. Duyt s tm k t s u tin, c tip s v ghi vo bin n.
4. M output file g tn "data.out".
5. Ghi dng u tin "Tong cua n so:" vi n l gi tr c th c c ti bc 3.
6. c tng s trong n s t file f, ghi vo file g km du +/ v cng dn vo bin tng t.
7. Ghi gi tr tng t vo file g.
8. ng cc files f v g.
9. Thu hi min nh cp cho s.
phc tp: C n.
(* Pascal: data.pas *)
uses crt;
const fn = 'data.inp'; gn = 'data.out';
bl = #32; { Du cch }
nl = #13#10; { Xung u dng mi }
var n: integer;
function LaChuSo(c: char): Boolean;
begin
LaChuSo := (c >= '0') and (c <= '9');

end;
procedure Tong;
var i,t,x : integer;
s: string;
f,g: text;
begin
{ Mo input file f ten fn = "data.inp" doc dong dau tien vao s }
assign(f,fn); reset(f); readln(f,s);
i := 1; { Duyet s tim chu so dau tien }
while Not LaChuSo(s[i]) do inc(i);
n := 0; { Doc so trong s ghi vao n }
while LaChuSo(s[i]) do
begin
n := n*10 + (ord(s[i]) - ord('0'));
inc(i);
end;
assign(g,gn); rewrite(g); { Mo output file g ten gn="data.out" }
writeln(g,'Tong cua ',n,' so:'); { Ghi dong thu nhat vao g }
t := 0; { Khoi tri bien tich luy t }
for i := 1 to n do { Doc lan luot tung so x trong n so }
begin
read(f,x);
if x > 0 then write(g,' +',x) else write(g,' ',x);
t := t + x;
end;
writeln(g,' = ',t); { Ghi ket qua }
close(f); close(g); { Dong cac files }
end;
BEGIN
Tong;
writeln(nl,' Fini');
readln;
END.
// DevC++ Data
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
using namespace std;
// D A T A A N D V A R I A B L E
const char * fn = "data.inp";
const char * gn = "data.out";
int n;
// P R O T O T Y P E S
void Tong();
bool LaChuSo(char c);
// I M P L E M E N T A T I O N
int main(){
Tong();
cout << endl << endl << " Fini" << endl;
cin.get();
return 0;
}
bool LaChuSo(char c) { return (c >= '0' && c <= '9'); }
void Tong() {
const int mn = 100;
int i, t, x;
ifstream f(fn); // Mo input file f ten fn = "data.inp"
char *s = new char [mn]; // cap phat s
f.getline(s,mn,'\n'); // doc toan bo dong thu nhat
for (i = 0; i < strlen(s); ++i) // duyet xau s tim chu so
if (LaChuSo(s[i])) break;

n = 0; // khoi tri so n
while (LaChuSo(s[i])) { // doc so n
n = n*10 + int(s[i]-'0');
++i;
}
t = 0; // khoi tri bien tong t
ofstream g(gn); // Mo output file g ten gn = "data.out"
g << "Tong cua " << n << " so:" << endl;
for (i = 0; i < n; ++i) {
f >> x; // doc tung so x
if (x > 0) g << " +" << x; else g << " " << x;
t += x; // lay tong
}
g << " = " << t;
f.close(); // dong input file
g.close();
delete s; // thu hi bin s, nu cn
}

1.4 Xu con chung


Hy tm chiu di ln nht k trong s cc xu con chung ca hai xu x v y.
Th d, x = "xaxxbxcxd", y = "ayybycdy", chiu di ca xu con chung di nht l 4 ng vi xu "abcd".
Thut ton
Xt hm 2 bin s(i,j) l p s khi gii bi ton vi 2 tin t i:x v j:y. Ta c,
s(0,0) = s(i,0) = s(0,j) = 0: mt trong hai xu l rng th xu con chung l rng nn chiu di l 0;
Nu x[i] = y[j] th s(i,j) = s(i1,j1) + 1;
Nu x[i] y[j] th s(i,j) = Max { s(i1,j), s(i,j1) }.
ci t, trc ht ta mng tng l c th s dng mng hai chiu v vi qui c v[i][j] = s(i,j). Sau
ta ci tin bng cch s dng 2 mng mt chiu a v b, trong a l mng tnh bc th i1, b l
mng tnh bc th i, tc l ta qui c a = v[i1] (dng i1 ca ma trn v), b = v[i] (dng i ca ma trn
v). Ta c, ti bc i, ta xt k t x[i], vi mi j = 0..len(y)1,
Nu x[i] = y[j] th b[j] = a[j1] + 1;
Nu x[i] y[j] th b[j] = Max { a[j], b[j1] }.
Sau khi c d liu vo hai xu x v y ta gi hm XauChung xc nh chiu di ti a ca xu con
chung ca x v y. a,b l cc mng nguyn 1 chiu.
phc tp: C m.n, m = len(x), n = len(y).
(* XauChung.pas *)
function Max(a,b: integer): integer;
begin if a > b then Max := a else Max := b; end;
function XauChung(var x,y: string): integer;
var m,n,i,j: integer;
a,b: array[0..255] of integer;
begin
m := length(x); n := length(y);
fillchar(a,sizeof(a),0);
for i := 1 to m do
begin
for j := 1 to n do
if x[i] = y[j] then b[j] := a[j-1]+1
else b[j] := Max(a[j],b[j-1]);
a := b;
end;
XauChung := a[n];
end;
BEGIN
writeln;
writeln(XauChung('xabcxxxd','aybcydyy')); { 4 }
readln;
END.
// Dev-C++: XauChung.cpp

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


int XauChung(char *x, char *y) {
int i,j;
int m = strlen(x), n = strlen(y);
int a[n], b[n];
for (j = 0; j < n; ++j)
a[j] = (x[0] == y[j]) ? 1 : 0;
for (i = 1; i < m; ++i) {
b[0] = (x[i] == y[0]) ? 1 : 0;
for (j = 1; j < n; ++j)
if (x[i] == y[j]) b[j] = a[j-1] + 1;
else b[j] = Max(a[j],b[j-1]);
memmove(a,b,n*sizeof(int));
}
return a[n-1];
}
int main() {
cout << endl << XauChung("xaxxbcxd","aybcyydy"); // 4
cin.get();
return 0;
}

Cch lm test
Bn hy vit ra mt xu s no lm p s, tc l xu con chung, sau thm vo s mt s k t nhn
c xu x, ri li thm cho s mt s k t khc nhn c xu y.
Cc bi tng t
1. Xu chung 2. Cho hai xu x gm m v y gm n k t. Cn xa i t xu x dx k t v t xu y dy k t
thu c hai xu ging nhau. Hy xc nh gi tr nh nht ca tng dx+dy.
2. Dy con chung. Cho hai dy s nguyn a gm m v b gm n phn t. Cn xa i t nht l bao nhiu
phn t t mi dy trn thu c hai dy ging nhau.
Thut ton cho bi Xu chung 2
k = XauChung(x,y);
dx = len(x) k;
dy = len(y) k;

1.5 on chung
Hy tm chiu di ln nht k trong s cc on chung ca hai xu x v y.
Th d, x = "xabcxxabcdxd", y = "aybcyabcdydy" c chiu di ca on chung di nht l 4 ng vi on
"abcd".
Thut ton
Xt hm 2 bin s(i,j) l chiu di ln nht ca hai on ging nhau x[ik+1..i] v y[jk+1..j], k max.
Ta c,
Nu x[i] = y[j] th s(i,j) = s(i1,j1) + 1;
Nu x[i] y[j] th s(i,j) = 0.
p s s l Max { s(i,j) | 1 i len(x), 1 j len(y) }.
ci t ta c th s dng hai mng mt chiu nh bi trc. Ta cng c th s dng mt mng mt
chiu a v hai bin ph v v t. Bin t lu tm gi tr trc khi tnh ca a[j]. Bin v ly li gi tr t tnh
cho bc sau.
phc tp: C m.n, m = len(x), n = len(y).
(* DChung.pas *)
function Max(a,b: integer): t vit;
function DoanChung(x,y: string): integer;
var m,n,i,j,v,t,kmax: integer;
a: array[1..255] of integer;
begin
m := length(x); n := length(y); kmax := 0;
fillchar(a,sizeof(a),0);
for i := 1 to m do

begin
v := 0;
for j := 1 to n do
begin
t := a[j];
if x[i] = y[j] then a[j] := v+1
else a[j] := 0;
kmax := Max(kmax,a[j]);
v := t;
end;
end;
DoanChung := kmax;
end;
BEGIN
writeln(DoanChung('xabcxxabcdxd','aybcyabcdydy')); {4}
writeln(' Fini');
readln;
END.
// DevC++: DoanChung.cpp
int Max(int a, int b); // t vit
int DoanChung(char *x, char *y) {
int i, j, kmax = 0, v, t ;
int m = strlen(x), n = strlen(y);
int a[n];
memset(a,0,sizeof(a));
for (i = 0; i < m; ++i) {
v = 0;
for (j = 0; j < n; ++j) {
t = a[j];
if (x[i] == y[j]) a[j] = v + 1;
else a[j] = 0;
kmax = Max(kmax,a[j]);
v = t;
}
}
return kmax;
}
int main() {
cout << endl << DoanChung("xabcxxabcdxd","aybcyabcdydy");//4
cin.get();
return 0;
}
Cch lm test
Test 1. Trc ht vit mt xu s sau xy dng 2 xu x = y = s. p s len(s). Th d, x = y = s =
'abcaaabb'. p s: 8
Test 2. Sa li Test 1 bng cch thm vo x v y mt s k t khc nhau. p s: len(s). Th d, x =
'xy'+s+'uvz'; y = 'uv'+s+'xy'. p s: 8.
Test 3. Sa li Test 2 bng cch chn thm mt an nh ca s vo x v y. Th d, x = 'xy'+s+'uv'+s'; y = 'u'
+ s' + 'v'+ s +'xy' + s' vi s' = 'abcaaab' (ht 1 k t so vi s. p s: 8.
Cc bi tng t
1. on chung 2. Cho hai xu x gm m v y gm n k t. Tm on chung di nht ca hai xu ny. Kt
qu cho ra 4 gi tr dx, cx, dy, cy, trong x[dx..cx] = y[dy..cy] l hai on tm c.
2. on chung 3. Cho hai dy s nguyn a gm m v b gm n phn t. Xc nh chiu di ln nht k
hai dy cng cha k phn t lin tip nh nhau: a[i] = b[j], a[i+1] = b[j+1],,a[i+k1] = b[j+k1].
Thut ton cho bi on chung 2
Khi pht hin a[j] > kmax ta ghi nhn imax = i; jmax = j; kmax = k. Cui th tc ta tnh cx = imax; dx =
cxkmax+1; cy = jmax; dy = cykmax+1.

1.6 on lp
Nhng vin ngc lp trnh (Bentley)
Cho xu s cha n k t. Hy xc nh ba s nguyn i, j v k tha iu kin 1 i < j n, k l gi tr max tha
iu kin s[i] = s[j], s[i+1] = s[j+1], , s[i+k1] = s[j+k1]. Hai on bng nhau gm k k t trong s l
s[i..i+k1] v s[j..j+k1], i < j, k max c gi l hai on lp trong s.
Th d, s = 'xabababayyy' cho ta i = 2, j = 4, k = 5 ng vi on lp s[2..6] = 'ababa'.
Thut ton 1
Bi ny kh ging bi on chung. Xt hm 2 bin s(i,j) l chiu di ln nht ca hai on ging nhau
x[ik+1..i] v y[jk+1..j], i < j, k max. Ta c,
Nu x[i] = x[j] th s(i,j) = s(i1,j1) + 1;
Nu x[i] x[j] th s(i,j) = 0.
p s s l Max { s(i,j) | 1 i len(x), 1 j len(y), i < j }.
ci t ta c th s dng hai mng mt chiu nh bi trc. Ta cng c th s dng mt mng mt
chiu a v hai bin ph v v t. Bin t lu tm gi tr trc khi tnh ca a[j]. Bin v ly li gi tr t tnh
cho bc sau.
phc tp: C n2, n = len(s).
(* Repeat.pas *)
uses crt;
var i,j,k: integer;
procedure DoanLap(s: string; var imax, jmax, kmax: integer);
var n,i,j,v,t: integer;
a: array[1..255] of integer;
begin
n := length(s); kmax := 0;
fillchar(a,sizeof(a),0);
for i := 1 to n do
begin
v := 0;
for j := i+1 to n do
begin
t := a[j];
if s[i] = s[j] then a[j] := v+1
else a[j] := 0;
if kmax < a[j] then
begin
kmax := a[j]; imax := i-kmax+1; jmax := j-kmax+1;
end;
v := t;
end;
end;
end;
BEGIN
DoanLap('xabababayy',i, j, k);
writeln(i,' ', j, ' ',k); { i = 2, j = 4, k = 5 }
readln;
END.
// DevC++: Repeat.cpp
void DoanLap(char *s, int & imax, int & jmax, int & kmax) {
int i, j , v, t ;
int n = strlen(s);
int a[n];
kmax = 0;
memset(a,0,sizeof(a));
for (i = 0; i < n; ++i) {
v = 0;
for (j = i+1; j < n; ++j) {
t = a[j];
if (s[i] == s[j]) a[j] = v + 1;
else a[j] = 0;

if (kmax < a[j]) {


kmax = a[j]; imax = i-kmax+2; jmax = j-kmax+2;
}
v = t;
}
}
}
int main() {
int i, j, k;
DoanLap("xabababayy", i, j, k);
cout << endl << i << " " << j << " " << k;//i = 2, j = 4, k = 5
cin.get();
return 0;
}
Thut ton 2 (Bentley, Nhng vin ngc lp trnh)
1. Sp tng theo ch dn cc hu t ca s theo trt t t in. Gi dy c sp theo ch dn ny l id[1..n],
n = len(s).
2. Duyt dy c sp trong id, vi mi cp hu t ng k nhau s:id[i] v s:id[i1], i = 2..n ta gi hm
ComLen(id[i], id[i-1]) tnh chiu di ca khc u chung (hay tin t) di nht ca chng. p s khi
s l
Max { ComLen(id[i], id[i-1]) | i = 2..len(s) }
Th tc sp theo ch dn id xt cc hu t s:id[i] c thc hin theo gii thut quicksort nh sau:
void IdSort(char * s, int * id, int d, int c) {
int i = d, j = c, m = id[(i+j)/2], t;
while (i < j) {
while (Sanh(s,id[i],m) < 0) ++i;
while (Sanh(s,id[j],m) > 0) --j;
if (i <= j) {
t = id[i]; id[i] = id[j]; id[j] = t;
++i; --j;
}
}
if (d < j) IdSort(s,id,d,j);
if (i < c) IdSort(s,id,i,c);
}
Hm Sanh(s, i, j) so snh hai hu t s:i v s:j theo trt t t in hot ng theo nguyn tc sau: Ln
lt so snh cc cp k t s[i] v s[j] cho n cui xu, nu gp cp k t khc nhau u tin th xt: k t
no nh hn th xu cha n s nh hn xu kia.
int Sanh(char *s, int i, int j) { //so sanh 2 hau to s:i, s:j
int k = Min(strlen(s)-i, strlen(s)-j), v;
for (v = 0; v < k; ++v,++i,++j)
if (s[i] != s[j]) return (s[i] < s[j]) ? -1 : 1;
return (i < j) ? 1 : ((i > j) ? -1 : 0);
}
Hm ComLen(s, i, j) cho ra chiu di ln nht ca hai khc u ging nhau ca hai hu t s:i v s:j.
int ComLen(char *s, int i, int j) {
int k = Min(strlen(s)-i, strlen(s)-j);
for (int v = 0; v < k; ++v, ++i, ++j)
if (s[i] != s[j]) return v;
return k;
}
Thut ton Bentley khi s c trin khai qua hm sau,
void DoanLap(char *s, int & imax, int & jmax, int & kmax) {
int i, k;
int n = strlen(s);
int id[n];
for (i = 0; i < n; ++i) id[i] = i;
IdSort(s,id,0,n-1);
for (i = 1; i < n; ++i) {

if ((k = ComLen(s, id[i], id[i-1])) > kmax) {


kmax = k; imax = id[i]+1; jmax = id[i-1]+1;
}
}
if (imax > jmax) { i = imax; imax = jmax; jmax = i; }
}
(* DoanLap2.pas *)
uses crt;
var i,j,k: integer;
type mi1 = array[1..256] of integer;
function Min(a,b: integer): integer;
begin if a < b then Min := a else Min := b; end;
function Sanh(var s: string; i,j: integer): integer;
var k, v: integer;
begin
k := Min(length(s)-i,length(s)-j);
for v := 0 to k do
if s[i+v] <> s[j+v] then
begin
if s[i+v] < s[j+v] then Sanh := -1 else Sanh := 1;
exit;
end;
if i < j then Sanh := 1
else if i > j then Sanh := -1 else Sanh := 0;
end;
procedure IdSort(var s: string; var id: mi1; d,c: integer);
var i, j, m, t: integer;
begin
i := d; j := c; m := id[(i+j) div 2];
while (i <= j) do
begin
while Sanh(s,id[i],m) < 0 do inc(i);
while Sanh(s,id[j],m) > 0 do dec(j);
if (i <= j) then
begin
t := id[i]; id[i] := id[j]; id[j] := t;
inc(i); dec(j);
end;
end;
if d < j then IdSort(s,id,d,j);
if i < c then IdSort(s,id,i,c);
end;
function ComLen(var s: string; i, j: integer): integer;
var v,k: integer;
begin
k := Min(length(s)-i, length(s)-j);
for v := 0 to k do
if s[i+v] <> s[j+v] then
begin ComLen := v; exit end;
ComLen := k+1;
end;
procedure DoanLap(s: string; var imax, jmax, kmax: integer);
var n,i,j,k: integer;
id: mi1;
begin
n := length(s); kmax := 0;
for i := 1 to n do id[i] := i;
IdSort(s,id,1,n);
for i := 2 to n do
begin
k := ComLen(s,id[i],id[i-1]);
if k > kmax then

begin
kmax := k; imax := id[i]; jmax := id[i-1];
end;
end;
if imax > jmax then
begin i := imax; imax := jmax; jmax := i end;
end;
BEGIN
DoanLap('xabababayy',i, j, k);
writeln; writeln(i,' ', j, ' ',k);
readln;
END.
Cch lm Test
Xy dng 4 xu X, Y, A v B khng c cc k t chung. Ghp XABAB...ABY mt s ln. p s: i =
len(X) +1, j = len(X)+Len(A)+Len(B)+1, k = (v1).(len(A)+len(b)) vi v l s ln lp cc cp AB.
Th d, vi X = 'xy'; Y = 'zt'; A = 'abcde'; B = 'fghhik' ta c th xy dng cc Test sau y.
Test 1. s = XABABY = 'xyabcdefghhikabcdefghhikzt'. p s i = 3, j = 2 + 5 + 6 + 1 = 14, k = 5+6 = 11.
Test 2. s = XABABABY = 'xyabcdefghhikabcdefghhikabcdefghhikabcdefghhikzt'. p s i = 3, j = 14, k
= 2*11 = 22.

1.7 T in
Olimpic Moscow
Cc t trong bi c hiu l mt dy lin tip cc ch ci a, b,, z. Mt file vn bn cha mt t in T
gm ti a n = 100 t khc nhau i mt. Mi t di khng qu 50 k t v c vit trn mt dng. Cho
mt t s di khng qu 200 k t. Hy cho bit cn xa i khi s ti thiu bao nhiu ch ci phn cn li
to thnh dy lin tip cc t trong t in T, mi t c th xut hin nhiu ln.
Th d,
dic.inp
6
abba
not
is
astra
saint
panama
saintpavnamtranaisnotsaintabba

dic.out
5

Gii thch
Sau khi xa 5 ch ci (gch di)
saintpavnamtranaisnotsaintabba
ta thu c dy ghp ca cc t 5, 6, 3, 2, 5,
1
saintpanamaisnotsaintabba

Thut ton
Ga s T l tp n t trong t in, s l t cn x l. Gi d(i) l hm cho p s khi gii bi ton vi tin t
i:s = s[1..i]. d(i) l s k t ti thiu cn xa khi s[1..i] phn cn li ca s[1..i] to thnh dy lin tip
cc t trong t in T. Vi mi t w di m k t trong t in T ta xt hm Nhung(w,i) c chc nng nhng
t w vo tin t i:s nh sau. Hm cho ra ch s v tha hai iu kin sau:
1. w l xu con ca s[v..i], ngha l nu xa i mt s k t khi s[v..i] ta s thu c t w,
2. s[v] = w[1], s[i] = w[m].
Nu w c nhng trong s[v..i] th s k t cn xa khi s[v..i] thu c t w s l iv+1len(w). Nu
t w c chn th tng s k t cn xa khi tin t i:s s l d(v1) + iv+1len(w). Ta cn chn w sao
cho gi tr ny t min. Vy,
d(i) = min { d(v1) + iv+1len(w) | w T, v = Nhung(w,i) }
Khi w khng th nhng c trong s[1..i] ta t v = Nhung(w,i) = 0 (pascal) hoc 1 (C).
(* TuDien.pas *)
uses crt;
const fn = 'dic.inp'; gn = 'dic.out'; nl = #13#10; bl = #32;
type str = string[52];
var f,g: text;
s: string[202];
w: array [1..102] of str;
n: integer;
d: array[0..202] of integer;

kq: integer;
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f); readln(f,n);
for i := 1 to n do readln(f,w[i]);
readln(f,s); close(f);
end;
procedure Ghi(v: integer);
begin
assign(g,gn); rewrite(g);
writeln(g,v);
close(g);
end;
function Nhung(var w: str; i: integer): integer;
var j: integer;
begin
Nhung := 0; j := length(w);
if j > i then exit;
if w[j] <> s[i] then exit;
for i := i downto 1 do
if (s[i] = w[j]) then
begin
dec(j);
if j = 0 then begin Nhung := i; exit; end;
end;
end;
function Min(a,b: integer): integer;
begin if (a < b) then Min := a else Min := b; end;
procedure Tinhd(i: integer);
var j,v: integer;
begin
d[i] := d[i-1]+1;
for j := 1 to n do
begin
v := Nhung(w[j],i);
if v > 0 then d[i] := Min(d[i], d[v-1]+i-v+1-length(w[j]));
end;
end;
function XuLi: integer;
var m, i: integer;
begin
d[0] := 0; m := length(s);
for i := 1 to m do Tinhd(i);
XuLi := d[m];
end;
BEGIN
Doc;
kq := XuLi; Ghi(kq);
writeln(nl,nl,kq,nl,' Fini '); readln;
END.
// DevC++: TuDien.cpp
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
using namespace std;
// D A T A A N D V A R I A B L E
const char * fn = "dic.inp";
const char * gn = "dic.out";
char w[102][52];

char s[202];
int d[202];
int n, lens;
// P R O T O T Y P E S
void Doc();
void Xem();
int Nhung(char *, int i);
int XuLi();
void Tinhd(int);
int Min(int, int);
void Ghi(int);
// I M P L E M E N T A T I O N
int main(){
Doc(); Xem();
int kq = XuLi();
Ghi(kq);
cout << endl << kq;
cout << endl << endl << " Fini" << endl;
cin.get();
return 0;
}
void Ghi(int v) {
ofstream g(gn);
g >> v;
g.close();
}
int Min(int a, int b) { return (a < b) ? a : b; }
void Doc() {
ifstream f(fn);
f >> n;
for (int i = 0; i < n; ++i) f >> w[i];
f >> s; lens = strlen(s);
f.close();
}
void Xem() {
cout << endl << n << " " << s;
for (int i = 0; i < n; ++i) cout << endl << w[i];
}
// Nhung tu w vao tien to s:i
int Nhung(char *w, int i) {
int j = strlen(w)-1;
if (i < j) return -1;
if (w[j] != s[i]) return -1;
for (; i >= 0; --i)
if (w[j] == s[i]) {
--j;
if (j < 0) return i;
}
return -1;
}
int XuLi() {
for (int i = 0; i < lens; ++i) Tinhd(i);
return d[lens-1];
}
void Tinhd(int i) {
int j, k, v;
d[i] = (i == 0) ? 1 : (d[i-1]+1);
for (j = 0; j < n; ++j)
if ((v = Nhung(w[j],i)) >= 0) {
k = (v == 0) ? 0 : d[v-1];
d[i] = Min(d[i], k+i-v+1-strlen(w[j]));
}
}

phc tp. C p.n.m, trong p = len(s), n l s t trong t in T, m l chiu di ca t di nht trong


T.
Ch thch Bn c th ci tin chng trnh nh sau. Khi c d liu v t chc t in T bn c th loi
trc khi T nhng t w no m k t u tin w[1] hoc k t cui cng w[m] khng xut hin trong s v
khi chc chn l hm Nhung s cho gi tr 1. Tt hn c l bn cho w trt trong s xc nh xem w
t lt ti cc ch s no trong s.

1.8 TEFI
TEFI.INP
15 27
...........***.............
***.........*.....****.....
*...........*.....*........
***...............***......
*....***********..*........
*........*........*..*****.
***..*...*...***.....*.....
.....*...*....*..*...*.....
.....*...*....*..*...****..
.........*....*..*...*.....
..****...*.......*...*.....
..*......*..*....*...****..
..***....*..*..............
..*.........*..............
..*.........*..............

Thut ton

TEFI.OUT
3 2 2 3

Trong text file tn TEFI.INP gm n dng v m ct


ngi ta dng du chm '.' to thnh mt bng
nn. Trn bng nn ngi ta dng du sao '*'
vit cc ch IN HOA T, E, F v I theo cc qui
tc sau:
- chn phng, khng c chn
- n nt
- cc nt song song khng dnh nhau
- cc nt ca hai ch khng dnh nhau m cch
nhau t nht mt du chm
Hy m s ch ci mi loi.
Th d bn cho bit c 3 ch T, 2 ch E, 2 ch F
v 3 ch I.

Ta xt hai dng x v y lin tip nhau trong bng nn v th pht hin c trng ca cc ch ci da trn 2
dng ny. Ta thy, ch T c c trng duy nht (khng ln vi cc ch ci khc) l u trn gm 1 vach
ngang () v 1 s ng (|) dnh nhau. Ch I c c trng duy nht l mt s ng (|). Trong ch E c 2 nt
ngang trn v 2 nt ngang di, ch F c 2 nt ngang trn v 1 nt ngang di.

x
y

i
*
*

u trn
ch T

i
.
*

u trn
ch I

.
.

i
*
*

Nt ngang
trn v
gia ca
ch E v F

.
.

i
*
*

Nt ngang
di ca
ch E v F

dnt = s nt ngang trn.


dnd = s nt ngang di.
dx = m s ch X;
X = {T,E,F,I}.
Mi ch E c 2 nt ngang trn v
2 nt ngang di. Mi ch F c 2
nt ngang trn v 1 nt ngang
di.
de+df = dnt / 2; de = dnd dnt/2.
df = dnt/2 de.

tin x l ta thm vo u v cui mi xu mt du chm '.'. Cc trng hp cn xt c m t chi tit


di dng bng quyt nh.
Bng quyt nh cho bi ton TEFI
x[i] = '*'
Bng quyt nh gm 2 phn: phn iu kin v
phn quyt nh.Cc iu kin c lit k c
x[i1] = '*'
lp nhau.
iu kin x[i+1] = '*'
Gi tr 1 ng vi iu kin ng (true), 0 ng vi
y[i] = '*'
iu kin sai (false), du cho bit iu kin ny
y[i1] = '*'
khng cn xt.
y[i+1] = '*'
Bng c c theo ct: nu cc iu kin trong
T (ch T)
ct thuc phn iu kin c tha th quyt nh
Quyt
(nt ngang trn)
ti ct c chn.
nh
L (nt ngang di)
x dng trn; y dng di.
I (ch I)

1
1
1
1

0
1
0
0

1
0
1
1
0
1

1
1

Da vo bng quyt nh ta duyt ng thi dng trn x v dng di y m cc gi tr sau:


dt l s lng ch T, di l s lng ch i, dnt l s lng nt ngang trn v dnd l s lng nt ngang
di L. T cc gi tr dnt v dnd ta d dng tnh c s lng ch E v s lng ch F. V mi ch E v
mi ch F u c cng 2 nt ngang trn nn de + df = dnt/2 (1). Mi ch E c 2 nt ngang di, mi ch F
c 1 nt ngang di nn 2.de + df = dnd (2). Tr tng v ca (2) cho (1) ta thu c de = dnd dnt/2. T
(1) ta suy ra df = dnt/2 de.
phc tp. c m.n = dung lng input file.
(* TEFI.PAS *)
uses crt;
const fn = 'tefi.inp'; gn = 'tefi.out';
bl = #32; nl = #13#10; ss = '*'; cc = '.';
var x, y: string;
dt, de, df, di: integer;
n, m: integer;
dnt, dnd: integer;
f,g: text;
procedure EF(i: integer);
begin
if (x[i+1] = ss) then inc(dnt)
else if (y[i+1] = ss) then inc(dnd)
end;
procedure TEF(i: integer);
begin
if (y[i] = cc) then exit;
if (x[i-1] = cc) then EF(i)
else inc(dt);
end;
procedure II(i: integer); { x[i] = cc }

1
0
1
0
1

begin
if (y[i] = ss) and (y[i-1] = cc) and (y[i+1] = cc) then inc(di);
end;
procedure TEFI;
var i,j: integer;
begin
dt := 0; di := 0; dnt := 0; dnd := 0;
fillchar(x,sizeof(x),cc);
assign(f,fn); reset(f); readln(f,n,m);
for j := 1 to n do
begin
readln(f,y); y := cc + y + cc;
for i := 2 to m do
begin
if (x[i] = ss) then TEF(i) else II(i);
end;
x := y;
end;
close(f);
i := dnt div 2; { de + df } de := dnd - i; df := i - de;
end;
BEGIN
TEFI;
writeln('T = ',dt,' E = ',de,' F = ',df, ' I = ', di);
readln;
END.
// DevC++: TEFI.CPP
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
using namespace std;
const char * fn = "tefi.inp";
const char * gn = "tefi.out";
string x, y;
char ss = '*', cc = '.';
int n, m;
int dt, de, df, di, dnt, dnd;
// P R O T O T Y P E S
void TEFI();
void TEF(int);
void EF(int);
void II(int);
// I M P L E M E N T A T I O N
int main(){
TEFI();
cout << endl << " T: " << dt << "
E: " << de;
cout << "
F: " << df << "
I: " << di;
cout << endl << endl << " Fini "; // 3
cin.get();
return 0;
}
void TEF(int i) {
if (y[i] == cc) return;
if (x[i-1] == cc) EF(i);
else ++dt;
}
void EF(int i){
if (x[i+1] == ss) ++dnt;
else if (y[i+1] == ss) ++dnd;
}

void II(int i) {
if (y[i] == ss && y[i-1] == cc && y[i+1] == cc) ++di;
}
void TEFI() {
int i, j;
dt = di = dnt = dnd = 0;
ifstream f(fn);
f >> n >> m; f.get();
x = cc;
for (i = 0; i < 8; ++i) x = x + x;
for (j = 0 ; j < n; ++j) {
f >> y; y = cc + y + cc;
for (i = 1; i <= m; ++i)
if (x[i] == ss) TEF(i);
else II(i);
x = y;
}
f.close();
i = dnt / 2; // i = de + df
de = dnd - i; df = i - de;
}

1.9 E xic
EXIEC.INP
15 27
...........................
***...............****.....
*.................*........
***...............***......
*....***********..*........
*....*...*.....*..****.....
***..*.*.*.*.*.*...........
.....*.*.*.*.*.*..****.....
.......*...*.*.......*.....
.......*******....****.....
..****...............*.....
.....*............****.....
..****..*...*....*.........
.....*..*...*....*.........
..****..**********.........

EXIEC.OUT
2 2 1 2

Trong text file tn EXIEC.INP gm n dng v m


ct ngi ta dng du chm '.' to thnh mt
bng nn. Trn bng nn ngi ta dng du
sao '*' vit cc ch IN HOA E vi nt ngang
gia hng v pha ng, Ty, Nam v Bc.
Qui tc vit ging nh trong bi TEFI. Hy m
s ch ci mi loi.
Th d bn cho bit c 2 ch E (nt ngang
hng v pha ng), 2 ch (nt ngang
hng v pha Ty). 1 ch E p (nt ngang
hng v pha Nam), v 2 ch E nga (nt
ngang hng v pha Bc).

Thut ton
x

* *
ng
dd L

*
* *
Ty
dt

*
Nam
dn T

*
*

* *
Bc
db

c trng ca cc ch E xic. Cc bin dd, dt, dn,


db dng m s ln xut hin ca cc c trng.

Hai E Nam v E Bc c c trng duy


nht qua hng ca nt ngang gia
ging ch T (E Nam) v (E Bc). Mi
E ng c 2 nt dng L v mi E Ty c
2 nt dng . Ngoi ra, mi ch E Bc
cn c 1 nt L v 1 nt . Ta c
S ch E ng = (dd db)/2,
S ch E Ty = (dtdb)/2,
S ch E Nam = dn,
S ch E Bc = db.

phc tp. c m.n = dung lng input file.


(* EXIEC.PAS *)
uses crt;

const fn = 'Exiec.inp'; gn = 'Exiec.out';


bl = #32; nl = #13#10; ss = '*'; cc = '.';
var x, y: string;
dd, dt, dn , db: integer;
n, m: integer;
f,g: text;
procedure TayNam(i: integer);
begin
if (y[i-1] = ss) then inc(dft)
else if (x[i-1] = ss) and (x[i+1] = ss) then inc(dn)
end;
procedure DongBac(i: integer);
begin
if (y[i-1] = ss) then inc(db)
else inc(dd);
end;
procedure DongTayNamBac(i: integer);
begin
if (y[i+1] = ss) then DongBac(i) else TayNam(i);
end;
procedure EXIEC;
var i,j: integer;
begin
dd := 0; dt := 0; dn := 0; db := 0;
assign(f,fn); reset(f); readln(f,n,m);
fillchar(x,sizeof(x),cc);
for j := 1 to n do
begin
readln(f,y); y := cc + y + cc;
for i := 2 to m do
if (x[i] = ss) and (y[i] = ss) then DongTayNamBac(i);
x := y;
end;
close(f);
dd := (dd-db) div 2; dt := (dt-db) div 2;
end;
BEGIN
EXIEC;
writeln(dd,' ',dt, ' ', dn, ' ', db); readln;
END.
// DevC++: EXIEC.CPP
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
using namespace std;
const char * fn = "exiec.inp";
const char * gn = "exiec.out";
string x, y;
char ss = '*', cc = '.';
int n, m;
int dd, dt, dn, db; // huong tro cua vach giua:
// P R O T O T Y P E S
void EXIEC();
void DongTayNamBac(int);
void DongBac(int);
void TayNam(int);
// I M P L E M E N T A T I O N
int main(){
EXIEC();
cout << endl << dd << " " << dt;
cout << " " << dn << " " << db;

Dong Tay Nam Bac

cout << endl << endl << " Fini "; // 3


cin.get();
return 0;
}
void DongTayNamBac(int i) {
if (y[i+1] == ss) DongBac(i);
else TayNam(i);
}
void DongBac(int i){
if (y[i-1] == ss) ++db;
else ++dd;
}
void TayNam(int i) {
if (y[i-1] == ss) ++dt;
else if (x[i-1] == ss && x[i+1] == ss) ++dn;
}
void EXIEC() {
int i, j;
dd = dt = dn = db = 0;
ifstream f(fn);
f >> n >> m; x = cc;
for (i = 0; i < 8; ++i) x = x + x;
for (j = 0 ; j < n; ++j) {
f >> y; y = cc + y + cc;
for (i = 1; i <= m; ++i)
if (x[i] == ss && y[i] == ss) DongTayNamBac(i);
x = y;
}
f.close();
dd = (dd - db)/2; dt = (dt - db)/2;
}

Chng 2 X l dy lnh v biu thc

2.1 Val
Cho cc bin c gn tr a = 0, b = 1, c = 2,..., z = 25. Tnh tr ca biu thc s hc c vit ng c
php, cha cc tn bin, cc php ton +, , *, v / (chia nguyn) v cc cp ngoc ().
Th d, biu thc, (b+c)*(eb) + (yx) s c gi tr (1+2)*(41)+ (2423) = 3*3+1 = 10.
Thut ton
Do phi u tin thc hin cc php ton nhn (*) v chia (/) trc cc php ton cng (+) v tr (), ta qui
c cc php ton nhn v chia c bc cao hn bc ca cc php ton cng v tr. Gi s l string cha biu
thc, ta duyt ln lt tng k t s[i] ca s v s dng hai ngn xp v v c x l cc tnh hung sau:
1. Nu s[i] l bin 'a', 'b', th ta np tr tng ng ca bin vo ngn xp (stack) v.
2. Nu s[i] l du m ngoc '(' th ta np du vo ngn xp c.
3. Nu s[i] l cc php ton '+', '', '*', '/' th ta so snh bc ca cc php ton ny vi bc ca php
ton p trn ngn ngn xp c.
3.1. Nu Bac(s[i]) Bac(p) th ta ly php ton p ra khi ngn xp c v thc hin php ton
vi 2 phn t trn cng ca ngn xp v. Bc ny c lp n khi Bac(s[i]) > Bac(p). Sau
lm tip bc 3.2.
3.2 Np php ton s[i] vo ngn xp c.
4. Nu s[i] l du ng ngoc ')' th ta d dn v thc hin cc php ton trn ngn ngn xp c cho n
khi gp du '(' np trc .
Thut ton c xy dng trn gi thit biu thc s c vit ng c php. V bn cht, thut ton x l
v tnh ton ng thi tr ca biu thc s theo nguyn tc php ton sau hay l k php Ba Lan do nh ton
hc Ba Lan Lucasievics xut. Theo k php ny, biu thc (b+c)*(eb) + (yx) s c vit thnh
bc+eb*yx+ v c thc hin trn ngn xp v nh sau. Gi iv l con tr ngn ca ngn xp v, iv c
khi tr 0:
1. Np tr ca bin b vo ngn xp v: iv := iv + 1; v[iv] := (b); trong (b) l tr ca bin b.
2. Np tr ca bin c vo ngn xp v: iv := iv + 1; v[iv] := (c);
3. Thc hin php cng hai phn t trn ngn ngn xp v, ghi kt qu vo ngn di, b ngn trn:
v[iv1] := v[iv1] + v[iv]; iv := iv 1;
4. Np tr ca e vo ngn xp v: iv := iv + 1; v[iv] := (e);
5. Np tr ca b vo ngn xp v: iv := iv + 1; v[iv] := (b);
6. Thc hin php tr hai phn t trn ngn ngn xp v, ghi kt qu vo ngn di, b ngn trn:
v[iv1] := v[iv1] v[iv]; iv := iv 1;
7. Thc hin php nhn hai phn t trn ngn ngn xp v, ghi kt qu vo ngn di, b ngn trn:
v[iv1] := v[iv1] * v[iv]; iv := iv 1;
8. Np tr ca y vo ngn xp v: iv := iv + 1; v[iv] := (y);
9. Np tr ca x vo ngn xp v: iv := iv + 1; v[iv] := (x);
10. Thc hin php tr hai phn t trn ngn ngn xp v, ghi kt qu vo ngn di, b ngn trn:
v[iv1] := v[iv1] v[iv]; iv := iv 1;
11. Thc hin php cng hai phn t trn ngn ngn xp v, ghi kt qu vo ngn di, b ngn trn:
v[iv1] := v[iv1] + v[iv]; iv := iv 1;
Kt qu cui cng c trong v[iv].
Bn nh khi tr ngn xp c bng k t no khng c trong biu thc, th d '#'. Php ton ny s c bc
0 v dng lm phn t m x l tnh hung 3.
Bn cn t k hiu # vo y ca ngn xp c lm lnh canh. V khi quyt nh c np php ton p no
vo ngn xp c ta cn so snh bc ca p vi bc ca php ton trn ngn ca ngn xp c. Nh vy # s
c bc 0. Bn c th thm mt php kim tra pht hin li "chia cho 0" khi thc hin php chia. Bn
cng c th pht trin thm chng trnh c th x l cc biu thc c cha cc php ton mt ngi !,
++, . ... v cc li gi hm.
phc tp. c n, trong n l s k hiu trong biu thc.
(* Val.pas *)

uses crt;
const fn = 'val.inp'; gn = 'val.out';
nl = #13#10; bl = #32; mn = 500;
var
c: array[0..mn] of char; {Ngn xp c cha cc php ton}
ic: integer;
v: array[0..mn] of integer; {Ngn xp v cha tr ca cc bin}
iv: integer;
function LaBien(c: char): Boolean;
begin LaBien := (c in ['a'..'z']); end;
function LaPhepToan(c: char): Boolean;
begin LaPhepToan := (c in ['+','-','*','/']) end;
function Val(c: char): integer; { tr ca bin c }
begin Val := Ord(c)-ord('a'); end;
function Bac(p: char): integer; { Bc ca php ton p }
begin
if (p in ['+','-']) then Bac := 1
else if (p in ['*','/']) then Bac := 2
else Bac := 0;
end;
(* Thc hin php ton 2 ngi trn ngn ngn xp v *)
procedure Tinh(p: char);
begin
case p of
'+': begin v[iv-1] := v[iv-1] + v[iv]; dec(iv) end;
'-': begin v[iv-1] := v[iv-1] - v[iv]; dec(iv) end;
'*': begin v[iv-1] := v[iv-1] * v[iv]; dec(iv) end;
'/': begin v[iv-1] := v[iv-1] div v[iv]; dec(iv) end;
end
end;
procedure XuLiToan(p: char);
begin
while (Bac(c[ic]) >= Bac(p)) do
begin Tinh(c[ic]); dec(ic) end;
inc(ic); c[ic] := p; { nap phep toan p }
end;
procedure XuLiNgoac;
begin
while (c[ic] <> '(') do begin Tinh(c[ic]); dec(ic) end;
dec(ic); { Bo ngoac }
end;
function XuLi(s: string): integer;
var i: integer;
begin
ic := 0; c[ic] := '#'; iv := -1;
for i := 1 to length(s) do
if LaBien(s[i]) then begin inc(iv); v[iv] := Val(s[i]) end
else if s[i] = '(' then begin inc(ic); c[ic] := '(' end
else if LaPhepToan(s[i]) then XuLiToan(s[i])
else if s[i] = ')' then XuLiNgoac;
while (ic > 0) do begin Tinh(c[ic]); dec(ic) end;
XuLi := v[iv];
end;
BEGIN
writeln(nl,XuLi('(b+c)*(f-a+b-c+d)/(c*d+b)')); { 3 }
readln;
END.
// DevC++: Val
#include <string.h>
#include <fstream>
#include <iostream>

#include <stdio.h>
using namespace std;
// Mo ta D lieu va bien
const int mn = 500;
char s[mn]; // bieu thuc
char c[mn]; //ngan xep phep toan va dau (
int ic; // con tr ngn xp c
int v[mn]; //ngan xep tinh toan
int iv; // con tr ngn xp v
int kq; // ket qua
int n; // len s ki t trong biu thc
// Khai bo cc hm
int XuLi();
bool LaBien(char c); // kiem tra c la bien ?
bool LaPhepToan(char c); // kiem tra c la phep toan +, , *, / ?
void XuLiPhepToan(char pt);
void XuLiNgoac();
int Bac(char pt); // Bac cua phep toan +, (1), *, / (2)
int Val(char c); // Tinh tri cua bien c
void Tinh(char pt); // thuc hien phep toan pt
// Cai dat
int main() {
strcpy(s,"(b+c)*(e-b) + (y-x)");
cout << endl << " input: " << s;
kq = XuLi();
cout << endl << endl << " Dap so: " << kq << endl ;
cout << endl << endl << " Fini" << endl;
cin.get();
return 0;
}
int XuLi() {
ic = 0; c[ic] = '#'; n = strlen(s); iv = -1;
int i;
for (i = 0; i < n; ++i)
if (LaBien(s[i])) v[++iv] = Val(s[i]);
else if (s[i]=='(') c[++ic] = '(';
else if (s[i]==')') XuLiNgoac();
else if (LaPhepToan(s[i])) XuLiPhepToan(s[i]);
while (LaPhepToan(c[ic])) { Tinh(c[ic]); --ic; }
return v[iv];
}
// Val('A') = 0; Val('B') = 1; . . .
int Val(char c) { return (int)(c-'a'); }
int Bac(char pt) {
if (pt == '+' || pt == '-') return 1;
else if (pt == '*' || pt == '/') return 2;
else return 0;
}
bool LaBien(char c) { return (c >= 'a' && c <= 'z'); }
bool LaPhepToan(char c) {return(c=='+'||c=='-'||c=='*'||c=='/');}
void XuLiPhepToan(char pt) {
while (Bac(c[ic]) >= Bac(pt)) { Tinh(c[ic]); --ic; }
c[++ic] = pt;
}
void XuLiNgoac(){
while (c[ic] != '(') { Tinh(c[ic]); --ic; }
--ic; // bo dau '('
}
void Tinh(char pt) { // Thuc hien php toan pt
switch(pt) {
case '+': v[iv-1] = v[iv-1]+v[iv]; --iv; break;

case '-': v[iv-1] = v[iv-1]-v[iv]; --iv; break;


case '*': v[iv-1] = v[iv-1]*v[iv]; --iv; break;
case '/': v[iv-1] = v[iv-1]/v[iv]; --iv; break;
}
}

2.2 Xu thu gn
Mt xu ch gm cc ch ci A, B, C,...,Z c th c vit gn theo cc quy tc sau:
1. Xm gm m ch ci X;
2. (S)m gm m ln vit xu thu gn S.
Nu m = 0 th on cn vit s c b qua, nu m = 1 th c th khng vit m. Th d, (AB3 (C2D)2
(C5D)0)2A3 l xu thu gn ca xu ABBBCCDCCDABBBCCDCCDAAA.
Cho xu thu gn s. Hy vit dng y (cn gi l dng khai trin) ca xu ngun sinh ra xu thu gn s.
Trong xu thu gn c th cha cc du cch nhng cc du cch ny c coi l v ngha v do khng
xut hin trong xu ngun.
Thut ton
Ta trin khai theo k thut hai pha. Pha th nht: Duyt xu s v to ra mt chng trnh P phc v cho
vic vit dng khai trin pha th hai. Pha th hai: Thc hin chng trnh P to ra xu ngun.
Pha th nht: Duyt tng k t s[v] v quyt nh theo cc tnh hung sau:
Nu s[v] l ch ci C th c tip s m sau C v to ra mt dng lnh mi dng (n, C, m), trong
n l s hiu ring ca dng lnh, C l ch ci cn vit, m l s ln vit ch ci C;
Nu s[v] l du m ngoc '(' th ghi nhn v tr dng lnh n+1 vo stack st;
Nu s[v] l du ng ngoc ')' th c tip s m sau ngoc, ly gi tr t t ngn ngn xp v to ra
mt dng lnh mi dng (n, #, m, t). Dng lnh ny c ngha nh sau: Cn thc hin lp m ln
on trnh t dng lnh t n dng lnh n. Nu s m = 0 th ta xa cc dng lnh t dng t n
dng hin hnh n. Nu n = 1 th ta khng to dng lnh mi.
Vi th d cho, sau pha 1 ta s thu c chng trnh P gm cc dng lnh nh sau:
n
1
2
3
4
5
6
7

c
A
B
C
D
#
#
A

m
1
3
2
1
2
2
3

3
1

ngha ca dng lnh


Vit A 1 ln
Vit B 3 ln
Vit C 2 ln
Vit D 1 ln
Lp 2 ln t dng lnh 3 n dng lnh 5
Lp 2 ln t dng lnh 1 n dng lnh 6
Vit A 3 ln

Chng trnh P gm 7 dng lnh thu


c sau khi thc hin Pha 1 vi xu
(AB3(C2D)2(C5D)0)2A3.

Pha th hai: Thc hin chng trnh P.


Ta thc hin tng dng lnh ca chng trnh t dng 1 n dng n. Vi th d cho, sau khi thc hin 4
dng lnh u tin ta thu c kt qu ABBBCCD. Tip n dng lnh 5 cho ta bit cn thc hin vic lp
2 ln cc lnh t dng 3 n dng 5. Sau mi ln lp ta gim gi tr ca ct m tng ng. Khi m gim n 0
ta cn khi phc li gi tr c ca m. Mun vy ta cn thm mt ct na cho bng. Ct ny cha gi tr ban
u ca m khi cn ta c th khi phc li. Ta s gi ct ny l R. Theo gii trnh trn, sau khi thc hin
dng 5 ta thu c xu ABBBCCDABBBCCD. Vi dng lnh 6, lp lun tng t ta thu c xu
ABBBCCDABBBCCDABBBCCDABBBCCD
Cui cng, sau khi thc hin dng lnh 7 ta thu c kt qu
ABBBCCDABBBCCDAAA
phc tp C n, trong n l s k t trong xu input.
(* XauGon.pas *)
uses crt;
const mn = 500; BL = #32; NL = #13#10;
ChuSo = ['0'..'9']; ChuCai = ['A'..'Z'];
type mi1 = array[0..mn] of integer;
mc1 = array[0..mn] of char;
var M, T, R, st: mi1; { M: so lan lap; T: tu; R: luu, st: stack }
c: mc1; { Lenh }
p: integer; { ngon stack }
s: string;
v: integer; { chi dan cua s }

n: integer; { so dong lenh }


procedure Cach; begin while (s[v] = BL) do inc(v); end;
function DocSo: integer;
var so: integer;
begin so := 0; Cach;
if Not (s[v] in ChuSo) then begin DocSo := 1; exit; end;
while (s[v] in ChuSo) do
begin
so := so*10 + (Ord(s[v]) - ord('0'));
inc(v);
end;
DocSo := so;
end;
procedure LenhDon(ch: char);
var so: integer;
begin
inc(v); so := DocSo;
if so = 0 then exit;
inc(n); C[n] := ch; M[n] := so;
end;
procedure NapNgoac;
begin inc(v); inc(p); st[p] := n+1 end;
procedure LenhLap;
var tu, so: integer;
begin
inc(v); tu := st[p]; dec(p);
so := DocSo;
if (so = 0) then n := tu-1;
if (so < 2) then exit;
inc(n); C[n] := '#'; M[n] := so; T[n] := tu; R[n] := so;
end;
procedure Pha2;
var i,j: integer;
begin
for i := 1 to n do
begin
write(NL,i,'. ',C[i],BL,M[i],BL);
if C[i] = '#' then write(T[i],BL,R[i]);
end;
i := 1;
while (i <= n) do
begin
if (C[i] = '#') then
begin
dec(R[i]);
if (R[i] = 0) then begin R[i] := M[i]; inc(i) end
else i := T[i];
end
else
begin
for j := 1 to M[i] do write(C[i]);
inc(i);
end;
end;
end;
procedure KhaiTrien(var s: string);
var i: integer;
begin
s := s + '#'; v := 1; p := 0;
while (s[v] <> '#') do
begin
if (s[v] in ChuCai) then LenhDon(s[v])
else if (s[v] = '(') then NapNgoac

else if (s[v] = ')') then LenhLap


else inc(v);
end;
write(NL,s , ' = ');
Pha2;
end;
BEGIN
s := ' (AB3(C2D)2(C5D)0)2A3';
KhaiTrien(s);
readln;
END.
// DevC++: XauGon.cpp
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L E
const int mn = 500;
const char BL = 32;
char C[mn]; // noi dung lenh
int M[mn]; // so lan lap
int T[mn]; // lap tu dong lenh nao
int R[mn]; // luu gia tri M
int n; // con dem dong lenh
char s[mn]; // xau thu gon
int v; // chi so duyet s
int st[mn]; // stack
int p; // chi so ngon stack st
// P R O T O T Y P E S
void KhaiTrien(char *);
void LenhDon(char);
void LenhLap();
int DocSo();
void Cach();
bool LaChuSo(char);
bool LaChuCai(char);
void Pha2();
// I M P L E M E N T A T I O N
int main() {
strcpy(s," (AB3(C2D)2(C5D)0)2A3");
KhaiTrien(s);
cout << endl; system("PAUSE");
return EXIT_SUCCESS;
}
bool LaChuCai(char c) { return (c >= 'A') && (c <= 'Z'); }
bool LaChuSo(char c) { return (c >= '0') && (c <= '9'); }
void Cach() { while (s[v] == BL) ++v; }
int DocSo() {
int so = 0;
Cach();
if (!LaChuSo(s[v])) return 1;
while (LaChuSo(s[v])) {
so = so*10 + int(s[v]-'0'); ++v;
}
return so;
}
void LenhDon(char ch) {
int so;
++v; so = DocSo();
if (so == 0) return;
++n; C[n] = ch; M[n] = so;

}
void LenhLap() {
int so;
++v; // bo qua dau )
so = DocSo();
int tu = st[p--];
if (so == 0) { n = tu-1; return; }
if (so == 1) return;
++n; C[n] = '#'; M[n] = R[n] = so; T[n] = tu;
}
void KhaiTrien(char *s ) {
// Pha1
p = 0; n = 0; // init
for (v = 0; s[v];) {
if (LaChuCai(s[v])) LenhDon(s[v]);
else if (s[v] == '(') { st[++p] = n+1; ++v; }
else if (s[v] == ')') LenhLap();
else ++v;
}
Pha2();
}
void Pha2() {
int i, j;
cout << endl << s << " = ";
i = 1;
while (i <= n) {
if (C[i] == '#') {
--R[i];
if (R[i] == 0) { R[i] = M[i]; ++i; }
else i = T[i];
}
else {
for (j = 1; j <= M[i]; ++j) cout << C[i];
++i;
}
}
}

2.3 Robot
Mt Robot c lp trnh di chuyn trn mt phng ta xoy chia li n v. Chng trnh iu
khin Robot c vit di dng xu gn nh trong bi Xu gn v gm dy lnh vi ngha nh sau:
Gn i thng n bc qua cc im nguyn,
Rn quay phi n ln 45 ,
Ln quay tri n ln 45 .
Robot c t ti v tr xut pht l gc ta , mt hng theo trc oy.
Yu cu: Xc nh ta (x,y) ni Robot dng chn sau khi thc hin chng trnh ghi trong string s.
Th d, Sau khi thc hin chng trnh s = "(GR3(G2L)2(L5G)0)2G3" Robot s dng chn ti v tr
(10,4) trn mt phng ta .
Thut ton
Pha 1 hon ton ging bi Xu thu gn. Ring vi pha 2 ta cn thay lnh hin th bng vic tnh v tr ca
Robot sau khi thc hin mi dng lnh.
Ta m s 8 hng di chuyn trn mt phng
ta t 0 n 7. Vi mi hng ta xc nh
cc gi tr dx v dy khi cho Robot i 1 bc
theo hng . Th d, theo hng h = 0 th
Robot s di chuyn t ta (x,y) sang ta
(x, y + 1), nh vy dx = 0, dy = 1.
Cc gi tr ny c khi to sn trong mt
mng hai chiu huong trong dx =
huong[h][0], dy = huong[h][1].

7
(1,1)

0
(0,1)

6
(1,0)
5
(1,1)

1
(1,1)
2
(1,0)

4
(0,1)

3
(1,1)

V c 8 hng nn nu Robot ang hng mt v hng h th sau khi quay phi k ln hng mt ca Robot
s l h = (h+k) mod 8, cn khi quay tri k ln ta s c h = (h + n(k mod 8)) mod 8. Bn rng php tr
k n v trn vng trn n im s c i thnh php cng vi nk.
phc tp C n, trong n l s k t trong xu input.
(* Robot.pas *)
uses crt;
const mn = 500; BL = #32; NL = #13#10; xx = 0; yy = 1;
huong: array[0..7,0..1] of integer
= ( (0,1), (1,1), (1,0), (1,-1),
(0,-1), (-1,-1), (-1,0), (-1,1) );
ChuSo = ['0'..'9']; ChuCai = ['A'..'Z'];
type mi1 = array[0..mn] of integer;
mc1 = array[0..mn] of char;
var M, T, R, st: mi1; { M: so lan lap; T: tu; R: luu, st: stack }
c: mc1; { Lenh }
p: integer; { ngon stack }
s: string;
v: integer; { chi dan cua s }
n: integer; { so dong lenh }
x,y: integer; { Toa do Robot }
h: integer; { huong di chuyen cua Robot }
procedure Cach; begin while (s[v] = BL) do inc(v); end;
function DocSo: integer;
var so: integer;
begin so := 0; Cach;
if Not (s[v] in ChuSo) then begin DocSo := 1; exit; end;
while (s[v] in ChuSo) do
begin
so := so*10 + (Ord(s[v]) - ord('0'));
inc(v);
end;
DocSo := so;
end;
procedure LenhDon(ch: char);
var so: integer;
begin
inc(v); so := DocSo;
if so = 0 then exit;
inc(n); C[n] := ch; M[n] := so;
end;
procedure NapNgoac;
begin inc(v); inc(p); st[p] := n+1 end;
procedure LenhLap;
var tu, so: integer;
begin
inc(v); tu := st[p]; dec(p);
so := DocSo;
if (so = 0) then n := tu-1;
if (so < 2) then exit;
inc(n); C[n] := '#'; M[n] := so; T[n] := tu; R[n] := so;
end;
procedure ThucHien(i: integer);
begin
case C[i] of
'G': begin x:=x+M[i]*huong[h,xx];y:=y+M[i]*huong[h,yy] end;
'R': h := (h + M[i]) mod 8;
'L': h := (h + 8 - (M[i] mod 8)) mod 8;

end;
end;
procedure Pha2;
var i: integer;
begin
x := 0; y := 0; h := 0;
for i := 1 to n do
begin
write(NL,i,'. ',C[i],BL,M[i],BL);
if C[i] = '#' then write(T[i],BL,R[i]);
end;
i := 1;
while (i <= n) do
begin
if (C[i] = '#') then
begin
dec(R[i]);
if (R[i] = 0) then begin R[i] := M[i]; inc(i) end
else i := T[i];
end
else
begin
ThucHien(i); { thuc hien dong lenh i }
inc(i);
end;
end;
end;
procedure Go(var s: string);
begin
s := s + '#'; v := 1; p := 0;
while (s[v] <> '#') do
begin
if (s[v] in ChuCai) then LenhDon(s[v])
else if (s[v] = '(') then NapNgoac
else if (s[v] = ')') then LenhLap
else inc(v);
end;
write(NL,s , ' = ');
Pha2;
end;
BEGIN
s := '(GR3(G2L)2(L5G)0)2G3';
Go(s);
writeln(NL,NL,'Ket qua (x,y) = ',x,BL,y); { (x,y) = (10,-4) }
readln;
END.
// DevC++: Robot.cpp
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L E
const int mn = 500;
const char BL = 32;
char C[mn]; // noi dung lenh
int M[mn]; // so lan lap
int T[mn]; // lap tu dong lenh nao
int R[mn]; // luu gia tri M
int n; // con dem dong lenh
char s[mn]; // xau thu gon
int v; // chi so duyet s
int st[mn]; // stack

int p; // chi so ngon stack st


int x, y; // Toa do (x,y) cua Robot
const int xx = 0, yy = 1;
int step[8][2] = {{0,1},{1,1},{1,0},{1,-1},
{0,-1},{-1,-1},{-1,0},{-1,1}};
int h; // huong di chuyen cua Robot
// P R O T O T Y P E S
void Go(char *);
void LenhDon(char);
void LenhLap();
int DocSo();
void Cach();
bool LaChuSo(char);
bool LaChuCai(char);
void Pha2();
void ThucHien(int);
// I M P L E M E N T A T I O N
int main(){
strcpy(s,"(GR3(G2L)2(L5G)0)2G3"); // (x,y) = (10,-4)
Go(s);
cout << endl << x << " " << y;
cout << endl; system("PAUSE");
return EXIT_SUCCESS;
}
bool LaChuCai(char c) { return (c >= 'A') && (c <= 'Z'); }
bool LaChuSo(char c) { return (c >= '0') && (c <= '9'); }
void Cach() { while (s[v] == BL) ++v; }
int DocSo() {
int so = 0;
Cach();
if (!LaChuSo(s[v])) return 1;
while (LaChuSo(s[v])) {
so = so*10 + int(s[v]-'0'); ++v;
}
return so;
}
void LenhDon(char ch) {
int so;
++v; so = DocSo();
if (so == 0) return;
++n; C[n] = ch; M[n] = so;
}
void LenhLap() {
int so;
++v; // bo qua dau )
so = DocSo();
int tu = st[p--];
if (so == 0) { n = tu-1; return; }
if (so == 1) return;
++n; C[n] = '#'; M[n] = R[n] = so; T[n] = tu;
}
void Go(char *s ) {
cout << endl << "input: " << s;
// init
p = 0; n = 0;
for (v = 0; s[v];) {
if (LaChuCai(s[v])) LenhDon(s[v]);
else if (s[v] == '(') { st[++p] = n+1; ++v; }
else if (s[v] == ')') LenhLap();
else ++v;
}
Pha2();
}

void ThucHien(int i) {
switch(C[i]) {
case 'G': x += M[i]*step[h][xx]; y += M[i]*step[h][yy]; break;
case 'R': h = (h+M[i]) % 8; break;
case 'L': h = (h+8-(M[i]%8)) % 8; break;
}
}
void Pha2() {
int i;
cout << endl << s << " = ";
x = y = 0; h = 0; i = 1;
while (i <= n) {
if (C[i] == '#') {
--R[i];
if (R[i] == 0) { R[i] = M[i]; ++i; }
else i = T[i];
}
else {
ThucHien(i); // thuc hien dong lenh i
++i;
}
}
}

2.4 Hm nhiu bin


Mt s hm c s tham bin khng hn ch,
Th d 1: Hm ucln tnh c chung ln nht ca cc s nguyn c nh ngha nh sau:
ucln( ) = 0, khng c tham bin, qui c = 0
ucln(x) = |x|, ucln ca s x l gi tr tuyt i ca chnh s
ucln(a,b) = ucln(b,a),
ucln(a,0) = a,
ucln(a,b) = ucln(a mod b, b)
ucln(x1, x2,...,xn) = ucln (ucln(x1, x2,...,xn-1), |xn|), n 2.
Th d 2: Hm sum tnh tng ca cc s nguyn:
sum( ) = 0,
sum(x) = x,
sum(x1, x2,...,xn) = sum(sum(x1, x2,...,xn-1), xn), n 2.
Ngoi ra cn cc hm ly min, max ca dy phn t...
Cho mt biu thc c vit ng c php, cha cc hng nguyn, cc bin a, b,... c gn sn cc tr a
= 0, b = 1,..., cc php ton s hc +, , *, / (chia nguyn), % (chia d), cc cp ngoc v cc li gi hm
nhiu bin @. Hy tnh gi tr ca biu thc nu @ l hm ucln.
Th d, 16 s l gi tr ca biu thc (10+@(12,30+@(6,8))+17*@( )+2)*@(1,3). Tht vy, ta c @( ) =
0; @(6,8) = 2; @(12,30+@(6,8)) = @(12,30+2) = @(12,32) = 4; @(1,3) = 1;
(10+@(12,30+@(6,8))+17*@( )+2)*@(1,3) = (10+4 + 17*0 +2)*1 = 16*1 = 16.
Thut ton
Ta m rng thut ton ca bi Val c th x l thm cc trng hp sau. Th nht, chng trnh phi
nhn bit c php ton o du. y l php ton 1 ngi khc vi php tr l php ton 2 ngi. Th d,
biu thc a + b c php ton o du. Php ny cng kh d nhn bit. Nu gp du v trong ngn ca
ngn xp c khng cha php ton no th php ny s l php ton i du. Ta np vo ngn xp c k hiu
! cho php i du nhm phn bit tng minh vi vi php ton tr. K thut ny c th gy nhp nhng,
th d, khi x l biu thc ab th du gp u tin nn trong ngn xp c khng cha php ton no. H
thng s coi l php ton i du. Ta khc phc tnh hung ny bng cch sau. Sau khi thc hin ht cc
php ton trong ngn xp c, nu trong ngn xp tnh ton t cn hn 1 phn t th ta cng dn kt qu vo
t[1]. Nh vy ta gi thit a b = a+(b) trong l php i du. Th hai, chng trnh phi x li
c cc tnh hung gi hm @ vi cc tham bin khc nhau. Khi gp k hiu @ ta xc nh xem gia cp
ngoc ( ) c i tng no khng. Nu khng c, ta ghi nhn mt li gi hm rng trong ngn xp c. Trong
danh sch tham bin ca li gi hm c th cha du phy dng ngn cch cc tham bin. Ta cng np
dn cc du ngn ny vo ngn xp c. Th tc Cach b qua cc du cch trong xu input s, tm n k t c
ngha s[v] tip theo.

Vi hai ngn xp c dng ghi nhn cc du php ton v t dng cha cc gi tr cn tnh ton ta t
chc c duyt xu input s v x l nh sau.
1. Khi tr cc ngn xp,
2. Vi mi k t s[v] ta xt
2.1 s[v] = '@': Np @ vo c; c tip s xc nh xem gia cp ngoc ( ) c k hiu no
khng. Nu khng c: np thm $ vo c ghi nhn li gi hm rng;
2.2 s[v] = '(': Np ( vo c;
2.3 s[v] l ch s '0'..'9': c s ny v np vo ngn xp t;
2.4 s[v] l tn bin (ch ci 'a'..'z'): Np tr ca cc bin ny vo ngn xp t. Tr ca bin x c
tnh theo cng thc x 'a';
2.5 s[v] l du phy: Thc hin cc php ton (nu c) trn ngn ngn xp c tnh tr ca biu
thc ng vi tham s ny. Th d, s = "@(a+1,..." th ta phi tnh tr ca a + 1 trc khi gi hm;
2.5 s[v] = ')': Ta cn xc nh xem du ')' ng mt biu thc con hay ng danh sch tham
bin ca mt li gi hm. Trc ht ta thc hin cc php ton (nu c) trn ngn ngn xp c
tnh tr ca biu thc kt thc bng du ')'. K n ta duyt ngc ngn xp c xc nh v tr
ca du '('. St trc v tr ny c th c du @ hoc khng. Nu c ta tnh hm. Nu st sau '(' l
k hiu '$' th ta hiu l hm rng, ta sinh tr 0 cho ngn xp t.
2.6 s[v] l du cc php ton +, , *, /, %: Ta thc hin cc php ton bc cao trn ngn ngn
xp c ri np php ton s[v] ny vo c. Ring vi php ta cn xc nh xem c phi l php
o du hay khng.
(* Func.pas *)
uses crt;
const bl = #13#10; nl = #32; mn = 500;
var
c: array[0..mn] of char; { ngan xep phep toan }
ic: integer;
{ ngon ngan xep c }
t: array[0..mn] of integer; { ngan xep tinh toan }
it: integer;
{ ngon ngan xep t }
s: string; { input }
v: integer; { duyet s }
function Ucln(a,b: integer): integer;
var r: integer;
begin a := abs(a); b := abs(b);
while b > 0 do
begin r := a mod b; a := b; b := r; end;
Ucln := a;
end;
procedure Cach;
begin while s[v] = bl do inc(v) end;
function LaBien(c: char): Boolean;
begin LaBien := (c in ['a'..'z']); end;
function LaChuSo(c: char): Boolean;
begin LaChuSo := (c in ['0'..'9']); end;
function LaPhepToan(c: char): Boolean;
begin LaPhepToan := (c in ['+','-','*','/','%','!']) end;
function Val(c: char): integer;
begin Val := Ord(c)-ord('a'); end;
function Bac(p: char): integer;
begin
if (p in ['+','-']) then Bac := 1
else if (p in ['*','/', '%']) then Bac := 2
else if (p = '!') then Bac := 3
else Bac := 0;
end;
function DocSo: integer;
var so: integer;
begin
so := 0;
while LaChuSo(s[v]) do

begin
so := so*10 + Ord(s[v])-ord('0');
inc(v);
end;
DocSo := so;
end;
procedure Tinh(p: char);
begin
case p of
'+': begin t[it-1] := t[it-1] + t[it]; dec(it) end;
'-': begin t[it-1] := t[it-1] - t[it]; dec(it) end;
'*': begin t[it-1] := t[it-1] * t[it]; dec(it) end;
'/': begin t[it-1] := t[it-1] div t[it]; dec(it) end;
'%': begin t[it-1] := t[it-1] mod t[it]; dec(it) end;
'!': begin t[it] := -t[it] end; { php o du }
end
end;
procedure Napc(ch: char); begin inc(ic); c[ic] := ch end;
procedure NapBien(x: char);
begin
inc(v); inc(it); t[it] := Val(x);
end;
procedure NapSo;
var so: integer;
begin
inc(it); t[it] := DocSo;
end;
procedure NapPhepToan(p: char);
begin
inc(v);
if p = '-' then
if Not LaPhepToan(c[ic]) then begin Napc('!'); exit end;
while (Bac(c[ic]) >= Bac(p)) do begin Tinh(c[ic]); dec(ic) end;
Napc(p);
end;
procedure NapPhay;
begin
inc(v);
while LaPhepToan(c[ic]) do begin Tinh(c[ic]); dec(ic) end;
Napc(',');
end;
procedure NapNgoac;
begin
inc(v); Napc('(');
end;
procedure NapHam;
begin
inc(v); Napc('@');
Cach; NapNgoac; { bo qua ( }
Cach; if s[v] = ')' then { Ham rong } Napc('$');
end;
procedure XuLiHam(i: integer);
var j,kq: integer;
begin
if c[i+1] = '$' then
begin
inc(it); t[it] := 0;
ic := i - 2;
exit
end;
kq := 0;
for j := it-ic+i to it do kq := Ucln(kq,t[j]);
it := it-ic+i; t[it] := kq;

ic := i - 2;
end;
procedure XuLiNgoac; { gap ) }
var i: integer;
begin
inc(v);
while LaPhepToan(c[ic]) do begin Tinh(c[ic]); dec(ic) end;
i := ic;
while (c[i] <> '(') do dec(i); { Tim ngoac ( }
if c[i-1] = '@' then XuLiHam(i) else dec(ic); { Bo ( }
end;
function BieuThuc(var s: string): integer;
var i: integer;
begin
s := s + '#'; ic := 1; c[ic] := '#'; it := 0; v := 1;
while (s[v] <> '#') do
if LaBien(s[v]) then NapBien(s[v])
else if LaChuSo(s[v]) then NapSo
else if LaPhepToan(s[v]) then NapPhepToan(s[v])
else if s[v] = ',' then NapPhay
else if s[v] = '(' then NapNgoac
else if s[v] = '@' then NapHam
else if s[v] = ')' then XuLiNgoac
else inc(v);
while (LaPhepToan(c[ic])) do begin Tinh(c[ic]); dec(ic) end;
for i := 2 to it do t[1] := t[1]+t[i];
BieuThuc := t[1];
end;
BEGIN
s := '@(-70,12+10-b,@(y+5,10)*c+12)';
writeln(nl,s, ' = ',BieuThuc(s)); { 7 }
readln;
END.
// Dev-C++: Func
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L E
const int mn = 500;
const char BL = ' ';//32;
char c[mn]; // stack lenh
int ic; // ngon stack c
int t[mn]; // stack tinh toan
int it; // ngon stac v
int v; // duyet s
char s[mn]; // xau input
// P R O T O T Y P E S
int BieuThuc(char *);
int DocSo();
void Cach();
bool LaPhepToan(char);
bool LaChuSo(char);
bool LaBien(char);
int Val(char);
int Bac(char);
void NapHam();
void NapNgoac();
void NapSo();
void NapPhay();
void XuLiNgoac();

void XuLiHam(int);
void Tinh(char);
void XuLiToan(char);
int Ucln(int , int);
// I M P L E M E N T A T I O N
int main(){
strcpy(s,"(10+@(12,30+@(6,8))+17*@()+2)*@(1,3)");
cout << endl << "Ket qua: " << BieuThuc(s); // 16
cout << endl; system("PAUSE");
return EXIT_SUCCESS;
}
int Ucln(int a, int b) {
int r;
a = abs(a); b = abs(b);
while (b) { r = a % b; a = b; b = r; }
return a;
}
int Bac(char p) {
if (p == '+' || p == '-') return 1;
else if (p == '*' || p == '/' || p == '%') return 2;
else if (p == '!') return 3;
else return 0;
}
bool LaChuSo(char c) { return (c >= '0') && (c <= '9'); }
bool LaPhepToan(char c) {
return (c=='!' || c=='+'||c=='-'||c=='*'||c=='/'||c=='%');
} // ! phep dao dau
bool LaBien(char c) { return (c >= 'a') && (c <= 'z'); }
int Val(char x) { return int(v-'0'); }
void Cach() { while (s[v] == BL) ++v; }
int DocSo() {
int so = 0;
Cach();
if (!LaChuSo(s[v])) return 1;
while (LaChuSo(s[v])) {
so = so*10 + int(s[v]-'0'); ++v;
}
return so;
}
void NapNgoac() {
c[++ic] = '('; ++v;
}
void NapHam() {
c[++ic] = '@'; ++v; // bo qua dau @ trong s
Cach(); // tim dau (
c[++ic] = s[v]; // Nap (
++v; // bo qua dau ( tring s
Cach(); if (s[v]==')') c[++ic] = '$';// ham rong
}
void NapSo() { t[++it] = DocSo();}
void NapVal(char x) { t[++it] = Val(x); ++v;}
void Tinh(char p) {
switch(p) {
case '+': t[it-1] += t[it]; --it; break;
case '-': t[it-1] -= t[it]; --it; break;
case '*': t[it-1] *= t[it]; --it; break;
case '/': t[it-1] /= t[it]; --it; break;
case '%': t[it-1] %= t[it]; --it; break;
case '!': t[it] = -t[it]; break;
}
}
void XuLiHam(int i) { // c[i-1..i] = @(
int kq = 0 ; // ket qua

if (c[i+1]=='$') { // ham rong


ic = i-2; t[++it] = 0;
return;
}
int k = ic - i + 1; // so tham bien
int jj = it;
it = it - k + 1;
for(int j = it; j <= jj; ++j)
kq = Ucln(kq, t[j]);
t[it] = kq;
ic = i-2;
}
void XuLiNgoac() { // Gap dau ): s[v] = ')'
int i;
++v; // bo qua ) trong s
while (LaPhepToan(c[ic])) { // Thuc hien cac phep toan tren ngon
Tinh(c[ic]); --ic;
}
i = ic;
while (c[i] != '(') --i;// tim dau ( trong c
// c[i] = '('
if (c[i-1] == '@') XuLiHam(i); // gap ham @
else --ic; // ko gap ham
}
void NapPhay() {
++v; // bo qua dau , trong s
while (LaPhepToan(c[ic])) {
Tinh(c[ic]); --ic;
}
c[++ic] = ',';
}
void XuLiToan(char p) {
++v; // bo qua ki tu trong s
if (p=='-')
if (!LaPhepToan(c[ic])) { c[++ic] = '!'; return; }
while (Bac(c[ic]) >= Bac(p)) {
Tinh(c[ic]); --ic;
}
c[++ic] = p;
}
int BieuThuc(char *s ) {
cout << endl << "input: " << s << endl;
// init
ic = it = 0; c[++ic] = '#';
for (v = 0; s[v];) {
if (s[v] == '@') NapHam();
else if (s[v] == '(') NapNgoac();
else if (LaChuSo(s[v])) NapSo();
else if (LaBien(s[v])) NapVal(s[v]);
else if (s[v] == ',') NapPhay();
else if (s[v] == ')') XuLiNgoac();
else if (LaPhepToan(s[v])) XuLiToan(s[v]);
else ++v;
}
while (LaPhepToan(c[ic])) {
Tinh(c[ic]); --ic;
}
for (;it > 1; --it) t[1] += t[it];
return t[1];
}

2.5 Files
files.inp

files.out

Ngi ta cn x l mt s file trong s cc file c tn 1, 2, ...,48 hin

LOAD 3
MODI
SAVE 50
LOAD 4
MODI
SAVE 51
LOAD 50
INS 51
MODI
SAVE 52
LOAD 1
INS 2
MODI
INS 52
SAVE 49
END

LOAD 4
MODI
SAVE 51
LOAD 3
MODI
INS 51
MODI
SAVE 50
LOAD 1
INS 2
MODI
INS 50
SAVE 49
END

lu trn a cng to ra mt file kt qu c tn 49. Qui trnh x l


c lp trnh sn. Chng trnh c vit bng ngn ng qun l file
gm cc lnh
LOAD i : c file i vo min nh RAM
MODI: sa ni dung hin c trn RAM
INS j: xen file j vo file trn RAM
SAVE j: ghi ni dung trn RAM vo file tn j.
END: kt thc chng trnh.
Tr lnh SAVE 49 cui cng, cc lnh SAVE u c s dng lu
tm cc kt qu trung gian vi cc tn file t 50 tr i. Vi cc file kch
thc ln, ngi ta mun hn ch s ln ghi a bng lnh SAVE nhm
tit kim thi gian x l. Hy thay chng trnh ghi trong files.inp bng
mt chng trnh tng ng ghi trong files.out vi t lnh SAVE. Hai
chng trnh c xem l tng ng nu file 49 cha kt qu cui
cng c ni dung ging nhau.

Trc ht ta xt mt th d minh ha. Gi s lc u mi file c ch s i cha mt s nguyn dng i+10, i


= 1, 2, ..., 48. Thao tc MODI lt cc ch s trong RAM, tc l vit dy s theo th t ngc li. Thao tc
INS i c s trong file i ri xen vo sau ch s u tin ca file hin lu trn RAM.
CHNG
TRNH TRONG
FILES.INP
LOAD 3

NI
DUNG
TRONG
FILE
13

MODI

RAM

CHNG
TRNH
TRONG
FILES.OUT

13

LOAD 4

31

MODI

NI
DUNG
TRONG
FILE
14

RAM

14
41

SAVE 50

31

31

SAVE 51

41

41

LOAD 4

14

14

LOAD 3

13

13

41

MODI

MODI

31

SAVE 51

41

41

INS 51

LOAD 50

31

31

MODI

INS 51

41

3411

SAVE 50

1143

1143

1143

LOAD 1

11

11

12

1121

MODI

41

3411
1143

SAVE 52

1143

1143

INS 2

LOAD 1

11

11

MODI

INS 2

12

1121

INS 50

1143

11143211

1211

SAVE 49

11143211

11143211

END

MODI
INS 52

1143

11143211

SAVE 49

11143211

11143211

1211

END

Kh trnh t thc hin hai chng trnh ghi trong input file FILES.INP v output file FILES.OUT c
gii trnh chi tit trong bng. Ni dung ghi trong 4 file mang m s 1, 2, 3 v 4 u tin ln lt l 11, 12,
13 v 14. Kt qu cui cng ca c hai chng trnh u ging nhau v bng 11143211. Chng trnh
ghi trn file inp cha 4 lnh SAVE trong khi chng trnh ghi trn file out cha 3 lnh SAVE. Bn cng
cn lu rng php xen file INS ni chung khng tha tnh giao hon v kt hp. minh ha ta tm qui
c ni dung ghi trong file c t gia cp ngoc []. Khi , [12] INS [13] = [1132], trong khi [13] INS
[12] = [1123], ngoi ra ([12] INS [13]) INS [14] = [1132] INS [14] = [114132], trong khi [12] INS ([13]
INS [14]) = [12] INS [1143] = [111432].

Thut ton

S 49

I 52

S 52

L 1

Cy t to t pha 1
Cc t vit tt
L LOAD
S SAVE
M MODIFY
I - INS

M
L 2

S 50

S 51

L 3

L 4

Thut ton c trin khai theo 2 pha: Pha c v Pha Ghi. Pha th nht, Pha c s c tng dng lnh
ca chng trnh ngun P t input file v to thnh mt cy t. Pha th hai, Pha Ghi ch n thun ghi li
cy t vo output file theo nguyn tc u tin lnh SAVE cho cy con phi. Ta trnh by chi tit cc k thut
ti hai pha.
Mi nt ca cy t c 4 thnh phn (C, f , L, R) trong C l ch ci u ca lnh LOAD, SAVE, MODI,
END, f l s hiu file (tn) trong dng lnh, L v R ln lt l con tr tri v phi ti nt tip theo trn cy.
Ta tm k hiu 0 l con tr NULL trong C++ v NIL trong Pascal.
1. Pha c s c ln lt tng dng lnh t chng trnh P vo bin string s v nhn bit lnh qua ch ci
u tin LOAD, SAVE, MODI, INS, END ri x l theo tng trng hp nh sau:
LOAD f : Nu file f cha xut hin th to mt nt mi v = (C, f, 0, 0) v nh du f l file xut hin.
Vic nh du c thc hin thng qua php gn p[f] = v trong p l mng cc con tr ti cc nt, f l
s hiu (tn) file, v l gi tr ca con tr c cp pht cho nt c khi to cho file f, p[f] = 0 (NULL/nil)
cho bit file f cha xut hin trong chng trnh P. Nu f xut hin th ta gn v l con tr ti nt khi
to cho file f, v = p[f];
SAVE f: Khng to nt mi, ch ghi nhn f vo bin lastsave bit php SAVE cui cng ca chng
trnh P s ghi kt qu vo file no. ng thi ta cng cn nh du p[f] = v bit rng file hin c trn
RAM l v c ghi vo file f;
MODI: To nt mi v = NewElem('M',1,v,0) t trn nt v hin hnh. Gi tr ca trng fnum c t
l 1 cho bit lnh ny khng quan tm n tn file v n ch MODIFY ni dung ca file hin c trn
RAM;
INS f: Nu file f cha xut hin th to nt mi v = NewElem('I',f,v,0), ngc li, nu file f xut hin th
to nt mi v = NewElem('I',-1,v,p[f]).
2. Pha Ghi Gi s t l cy to c sau pha 1. Ta vit th tc ToFile(t) duyt cy t theo nguyn tc u tin
cy con phi ghi vo output file chng trnh ti u s lnh SAVE nh sau. C th l ta duyt cy con

phi trc, sau n cy con tri v cui cng l nt gia. Th tc ny c tn RNL. Ta xt cc tnh hung
sau y.
2.1 Cy t ch c cy con tri L, t = (L,0): Ta ch vic gi th tc ToFile(L).
2.2 Cy t c c hai cy con tri L v phi R, t = (L,R) v hai cy con ny c gn vi nhau
bng lnh INS: Trc ht phi gi th tc ToFile(R) v ghi kt qu trung gian vo mt file tm
m, sau gi th tc ToFile(L) ri thm vo cui dng lnh INS m.
phc tp C n s dng lnh trong input file.
Bnh lun Thut ton trn cng b qua trng hp dy lnh SAVE f ging nhau lin tip cng nh trng
hp hai lnh lin tip l LOAD f v SAVE f vi cng mt tn file. Bn c th ci tin thm bng cch c
input file mt ln vo min nh v loi b cc lnh ny trc khi t chc cy t.
(* Files.pas *)
uses crt;
const fn = 'files.inp'; gn = 'files.out';
mn = 400; nl = #13#10; bl = #32;
chuso = ['0'..'9'];
type pelem = ^elem;
elem = record
com: char; { lenh }
fnum: integer; { so hieu file }
L,R: pelem; { tro trai, phai }
end;
var f,g: text; { f: input file; g: output file }
p: array[1..mn] of pelem; { danh dau cac file }
s: string; { dong lenh }
t: pelem; { cay nhi phan chuong trinh }
lastSave: integer;
tmp: integer; { file trung gian }
function DocSo: integer; { doc so tu dong lenh s }
var i, so: integer;
begin
so := 0;
i := 1;
while not (s[i] in chuso) do inc(i);
while (s[i] in chuso) do
begin
so := so*10 + ord(s[i]) - ord('0');
inc(i);
end;
DocSo := so;
end;
function NewElem(c: char; fno: integer; Lp,Rp: pelem): pelem;
var e: pelem;
begin
new(e);
e^.com := c; e^.fnum := fno;
e^.L := Lp; e^.R := Rp;
NewElem := e;
end;
function Load(fno: integer): pelem;
begin
if p[fno] = nil then
p[fno] := NewElem('L',fno,nil,nil);
Load := p[fno];
end;
procedure Save(v: pelem; fno: integer);
begin lastSave := fno; p[fno] := v; end;
function Ins(v: pelem; fno: integer): pelem;
begin
if p[fno] = nil then
Ins := NewElem('I',fno,v,nil)

else Ins := NewElem('I',-1,v,p[fno]);


end;
function Doc: pelem;
var i: integer;
v: pelem; { RAM }
begin
for i := 1 to mn do p[i] := nil;
assign(f,fn); reset(f);
while not seekeof(f) do
begin
readln(f,s); s := s + '#';
case s[1] of
'L': v := Load(DocSo);
'S': Save(v,DocSo);
'M': v := NewElem('M',-1,v,nil);
'I': v := Ins(v,DocSo);
'E': begin close(f); Doc := v; exit end;
end;
end;
end;
procedure ToFile(t: pelem);
var sav: integer;
begin
sav := 0;
if (t = nil) then exit;
if (t^.R <> nil) then
begin
inc(tmp); sav := tmp;
ToFile(t^.R);
writeln(g,'SAVE',bl,sav);
end;
ToFile(t^.L);
case(t^.com) of
'I': if (t^.R = nil) then writeln(g,'INS',bl,t^.fnum)
else if (sav > 0) then writeln(g,'INS',bl,sav);
'L': writeln(g,'LOAD',bl,t^.fnum);
'M': writeln(g,'MODI');
end;
end;
procedure Ghi(t: pelem);
begin
assign(g,gn); rewrite(g);
tmp := 49;
ToFile(t);
writeln(g,'SAVE',bl,lastsave,nl,'END');
close(g);
end;
BEGIN
t := Doc; Ghi(t);
writeln(nl,' Fini');readln;
END.
// Dev-C++: Files
#include <string.h>
#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 = "files.inp";
const char * gn = "files.out";
const char * LOAD = "LOAD";
const char * MODI = "MODI";
const char * INS = "INS";

const char * SAVE = "SAVE";


const char * END = "END";
const char star = '*'; // Node
const int mn = 400;
struct elem {
char com; int fnum; // com: lenh, fnum: file number
elem * L; elem * R; // tro trai, tro phai
};
elem* p[mn];
int tmp;
int lastsave;
// P R O T O T Y P E S
elem * Doc();
elem * Load(int);
elem *NewNode(char, int, elem*, elem*);
elem * Ins(elem *, int);
void Ghi(elem *t);
void ToFile(elem*);
ofstream g(gn);
// I M P L E M E N T A T I O N
int main() {
elem * t = Doc();
Ghi(t);
cout << endl; system("PAUSE");
return EXIT_SUCCESS;
}
void Ghi(elem *t) {
tmp = 49;
ToFile(t);
g << "SAVE " << lastsave << endl;
g << "END" << endl;
g.close();
}
void ToFile(elem *t) {
int sav = 0;
if (t == NULL) return;
if (t->R != NULL) {
++tmp; sav = tmp;
ToFile(t->R);
g << "SAVE " << sav << endl;
}
ToFile(t->L);
switch(t->com) {
case 'I': if (t->R == NULL) g << "INS " << t->fnum << endl;
else if (sav > 0) g << "INS " << sav << endl;
break;
case 'L': g << "LOAD " << t->fnum << endl;
break;
case 'M': g << "MODI" << endl;
break;
}
}
elem * Ins(elem *v, int fno) { // Tao node INS
elem * e = NewNode('I', -1, v, NULL);
if (p[fno] != NULL) e->R = p[fno];
else e->fnum = fno;
return e;
}
elem * Load(int fno) { // Tao node LOAD
if (p[fno] == NULL)
p[fno] = NewNode('L', fno, NULL, NULL);
return p[fno];
}

elem * NewNode(char cm, int i, elem * lp, elem * rp) {


elem * pt = new elem; // Tao node moi
pt->com = cm; pt->fnum = i;
pt->L = lp; pt->R = rp;
return pt;
}
elem * Doc() {// Doc vhuong trinh, tao cay
char s[10];
ifstream f(fn);
elem * v = NULL; // RAM
int i, fno;
for (i = 0; i < mn; ++i) p[i] = NULL;
while (1) {
f >> s; fno = 0;
switch(s[0]) {
case 'E': f.close(); return v; // END
case 'L': f >> fno; v = Load(fno); break; // LOAD
case 'S': f >> fno; lastsave = fno;
p[fno]= v; break; // SAVE
case 'I': f >> fno; v = Ins(v,fno); break; // INS
case 'M': v = NewNode('M',-1,v,NULL); break; // MODIFY
}
}
}
2.6 Gen
(Bi tng t)
Trong phng th nghim sinh hc phn t ngi ta bo qun cc on m di truyn, tm gi l cc on
gen trong cc t cha c bit c m s 1, 2,...,98. Cc gen c chnh sa v cy ghp vi nhau trn
bn th nghim T to ra mt gen cui cng t trong t cha s 99 theo mt chng trnh my tnh t
ng bao gm cc thao tc sau:
TAKE i : ly mt gen t t cha i t ln bn th nghim T,
MODI: lm sch, sa cha cc thng tin di truyn trong gen hin c trn bn th nghim T,
INS j: cy ghp gen hin c trn T vi gen trong t cha j, kt qu thu mt gen trn T,
STORE k: ct gen trn T vo t cha k,
END : kt thc chng trnh.
Vic ly v ct gi gen i hi cc th tc rt phc tp nn ngi ta cn hn ch n mc ti a cc thao
tc ny. Ngoi ra, lu rng vic cy ghp gen i vo gen j cho kt qu khc vi vic cy ghp gen j vo
gen i. Hy thay chng trnh cho trc bng mt chng trnh tng ng vi t lnh STORE nht theo
ngha cho cng kt qu thu c trong t cha 99 nh chng trnh ban u. Trong qu trnh thao tc
c php s dng cc t cha tm t 100 tr i .
2.7 Ti u ha chng trnh
(Bi tng t)
prog.inp
LOAD x
ADD y
SAVE 100
LOAD x
SUB y
SAVE 101
LOAD 100
MULT 101
SAVE z
END

prog.out
LOAD x
SUB y
SAVE 100
LOAD x
ADD y
MULT 100
SAVE z
END

Trong cc b x l mt a ch cc thao tc x l c thc hin trn


thanh ghi A, cc hng v bin c ghi trong min nh RAM vi cc a
ch 0, 1, 2,... Chng trnh c vit di dng mt dy tun t cc lnh
m my bao gm cc lnh sau
LOAD i: c d liu t a ch i vo thanh ghi A,
ADD j: cng s hin c trn thanh ghi A vi s c trong a
ch j, kt qu trn A, A := A+(j), trong (j) k hiu ni
dung c trong a ch j,
SUB j: A := A(j),
MULT j: A := A*(j),
DIV j: A := A/(j),
SAVE j: ghi ni dung trn thanh ghi A vo a ch j,
END : kt thc chng trnh.

Gi thit rng cc kt qu tnh ton trung gian c lu tm vo vng nh t do c a ch qui c t 100


tr i. cc php ton khng tha cc tnh cht giao hon v kt hp. Hy thay chng trnh ghi trn text
file tn prog.inp bng mt chng trnh tng ng vi t lnh SAVE nht v ghi kt qu vo text file tn
prog.out .
Th d, file prog.inp l chng trnh tnh z := (x+y)*(x-y) vi 3 lnh SAVE, file prog.out l chng trnh
tng ng vi 2 lnh SAVE.

2.8 Mc ca biu thc


Trong cc biu thc tnh ton ngi ta thng dng cc cp ngoc (...) nhm thnh cc biu thc con.
Mc ca biu thc c hiu l s lng ti a cc cp ngoc lng nhau trong biu thc, th d biu thc
(a+(bc)*d)(ab) c mc 2. Cho trc k cp ngoc v mc h. Hy cho bit c th xy dng c bao
nhiu biu thc mc h v s dng ng k cp ngoc. Th d, ta c 3 biu thc mc h = 2 s dng ng k
= 3 cp ngoc nh sau:
(()())
(())()
()(())
Dng hm: Level(k,h)
Test 1. Level(3,2) = 3;
Test 2. Level(19,18) = 35.
Thut ton
Gi s(k,h) l hm 2 bin cho ra s lng cc biu thc khc nhau c mc h v cha ng k cp ngoc. Xt
cp ngoc th k. Ta thy,
- Nu gi A l biu thc mc h1 cha ng k1 cp ngoc th (A) s l biu thc su h v cha
ng k cp ngoc.
- Nu gi B l biu thc mc h cha ng k1 cp ngoc th ( ) B v B ( ) s l hai biu thc mc h v
cha ng k cp ngoc. Tuy nhin trong trng hp ny ta phi loi i tnh hung ( ) B = B ( ). Tnh
hung ny ch xy ra duy nht khi B c dng dy cc cp ngoc mc 1: B = ( )( ). Khi ( ) B = ( )
( ) ( ) = B ( ).
Tm li, ta c
s(k,h) = s(k1,h1) + 2s(k1,h) vi h > 1, v
s(k,1) = 1, k = 1, 2, , vi k 1cp ngoc ch c th vit c 1 biu thc mc 1 gm dy lin tip k
cp ngoc ()()...().
Ngoi ra ta c
s(0,h) = 0, h > 0, vi 0 cp ngoc khng th xy dng c biu thc mc h > 0;
s(0,0) = 1, vi 0 cp ngoc c duy nht 1 biu thc mc 0 (qui c).
Ci t: Ta c th ci t hm s(k,h) vi k ln lp v 2 mng 1 chiu a v b, trong a[j] l gi tr ca hm
s(k1,j), b[j] l gi tr ca hm s(k,j), j = 1..h.
Trc ht ta khi tr ng vi k = 1: a[1] = b[1] = 1; a[i] = 0, i = 2..h vi ngha sau: c 1 cp ngoc th vit
c 1 biu thc mc 1, khng c cc biu thc mc trn 1.
Gi s ti bc lp th k1 ta tnh c cc gi tr ca hm s(k1,j) v lu trong mng a nh sau: a[j] =
s(k1,j), j = 1..h. Khi cc gi tr ca hm s(k,j) s c tnh v lu trong mng b nh sau:
b[1] = s(k,1) = 1
b[j] = s(k,j) = s(k1,j1) + 2s(k1,j) = a[j1] + 2a[j], j = 2..h
phc tp: k.h.
(* Level.pas *)
uses crt;
const bl = #32; nl = #13#10; mn = 1000;
function Level(k,h: integer): longint;
var a,b: array[0..mn] of longint;
i,j: integer;
begin
fillchar(a, sizeof(a),0); a[1] := 1; b[1] := 1;
for i := 2 to k do { i cap ngoac }
begin
for j := 2 to h do { i cap ngoac, muc j }
b[j] := a[j-1] + 2*a[j];
a := b;
end;
Level := a[h];
end;

BEGIN
writeln(nl, level(3,2), nl, level(19,18));
readln;
END.
// Dev-C++: Level
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
// P R O T O T Y P E S
int Level(int, int);
// I M P L E M E N T A T I O N
int main() {
cout << endl << endl << Level(19,18); // 35
cout << endl << endl << Level(3,2); // 3
cout << endl << endl << " Fini" << endl;
cin.get();
return 0;
}
int Level(int k, int h){
int h1 = h+1;
int *a = new int[h1];
int *b = new int[h1];
memset(a,0,d1*sizeof(int)); a[1] = b[1] = 1;
for (int i = 2; i <= k; ++i) {
a[1] = 1;
for (int j = 2; j <= h; ++j) b[j] = a[j-1] + 2*a[j];
memmove(a,b,h1*sizeof(int));
}
delete a; delete b;
return a[h];
}

2.9 Thp
(Bi tng t)
Cc em nh dng cc khi g hnh ch nht to nh khc nhau v c b dy 1 n v t chng ln nhau
to thnh mt cng trnh kin trc gm nhiu ta thp. Khi t trn phi nh hn khi di, s lng khi
cc loi l khng hn ch. cao ca cng trnh c tnh theo chiu cao ca thp cao nht trong cng
trnh. Vi k khi g c th xy c bao nhiu kiu cng trnh cao h.

3 cng trnh cao 2 c xy bng 3 khi g

2.10 Mi trang

Trong mt file vn bn c n t. Vi mi t th i ta bit chiu di vi tnh bng s k t c trong t . Ngi


ta cn cn l tri cho file vi rng m k t trn mi dng. Mi t cn c xp trn trn mt dng, mi
dng c th cha nhiu t v trt t cc t cn c tn trng. Hy tm mt phng n cn l sao cho
phn ht ln nht bn phi cc dng l nh nht. Gi thit rng mi t u c 1 du cch cui, d
nhin du cch ny c tnh vo chiu di t.
D liu vo: file vn bn PAGES.INP. Dng u tin cha hai s n v m.
Tip n l n chiu di t vi cc gi tr nm trong khong t 2 n m.
D liu ra: file vn bn PAGES.OUT. Dng u tin cha hai s h v k, trong h l phn tha ln nht
(tnh theo s k t) ca phng n tm c, k l s dng ca vn bn c cn l. Tip n l k s cho
bit trn dng phi xp bao nhiu t.
Cc s trn cng dng cch nhau qua du cch.
PAGES.INP
6 10
2 2 3 3 6 9

PAGES.OUT
3 3
3 2 1

ngha: Cn xp 6 t chiu di ln lt l 2, 2, 3, 3, 6 v 9 trn


cc dng di ti a 10 k t. Nu xp thnh 3 dng l (2,2,3,3)
(6) (9) th phn ht ti a l 4 (trn dng 2). Nu xp thnh 3
dng l (2,2,3) (3,6) (9) th phn ht ti a l 3 (trn dng 1).
Nh vy ta chn cch xp th hai vi 3 dng: Dng 1: 3 t; dng
2: 2 t; dng 3: 1 t.

Thut ton
Gi d(i) l p s ca bi ton vi i t u tin. Ta xt cch xp t w[i]. u tin ta xp w[i] ring 1 dng,
ht khi s l h = mv[i]. Nu ch ht cn ta li ko t i1 t dng trn xung, ht khi s l
h = hv[i1],... Tip tc lm nh vy n khi ht h khng cha thm t ko t dng trn xung. Mi
ln ko thm mt t j t dng trn vo dng mi ny ta c mt phng n. ht ca phng n ny s l
max (hv[j],d(j1)). Ta s chn phng n no t tr min trong s .
ci t ta s dng mng mt chiu d cha cc gi tr ca hm d(i). Ta khi tr cho v[0] = m+1 lm lnh
canh, d[1] = mv[1], v khi ch c 1 t th ta xp trn 1 dng duy nht v ht l m v[1].
xc nh s phn b s lng t trn mi dng ta dng mng tr ngc t[1..n] trong t[i] = j cho ta
bit cc t j, j+1,...,i cng nm trn mt dng theo phng n ti u. Sau ta gi qui mun mng t
tnh ra s lng cc t trn mi dng, ghi vo mng sl theo trt t ngc.
phc tp: C n2 v vi mi t i ta phi duyt ngc i ln. Tng cng c n t nn s ln duyt s l n.n.
(* Pages.pas *)
uses crt;
const mn = 200; bl = #32; nl = #13#10;
fn = 'pages.inp'; gn = 'pages.out';
type mi1 = array[0..mn] of integer;
var n,m,k,h: integer;
f,g: text;
v, d, t, sl: mi1;
(* -------------------------------------n - number of words; m - width of page;
k - number of lines; h - maximum of
white character of all lines;
v[i] - length of i-th word;
d[i] - solution result of input data v[1..i];
t[i] = j: all words j, j+1,...,i are in one line;
sl[i] - number of words in i-th line
------------------------------------------*)
procedure PP(var x: mi1; d,c: integer);
var i: integer;
begin for i := d to c do write(bl,x[i]); end;
function Min(a,b: integer): integer;
begin if a < b then Min := a else Min := b end;
function Max(a,b: integer): integer;
begin if a > b then Max := a else Max := b end;
procedure Doc;
var i: integer;
begin assign(f,fn); reset(f); readln(f,n,m);
writeln(n,bl,m);
for i := 1 to n do read(f,v[i]);

close(f);
end;
procedure Tinhd(i: integer);
var j,h, hmax: integer;
begin
h := m; j := i; d[i] := m+1;
while h >= v[j] do
begin
h := h - v[j]; hmax := Max(d[j-1],h);
if d[i] > hmax then
begin
d[i] := hmax; t[i] := j;
end;
dec(j);
end;
end;
function XuLi: integer;
var i: integer;
begin
t[0] := 0; v[0] := m+1; d[0] := 0;
for i := 1 to n do Tinhd(i);
XuLi := d[n];
end;
procedure Xep(i: integer);
begin
if (i = 0) then exit;
inc(k); sl[k] := i-t[i]+1;
Xep(t[i]-1);
end;
procedure Ghi;
var i: integer;
begin
assign(g,gn); rewrite(g);
writeln(g,h,bl,k);
for i := k downto 1 do write(g,sl[i],bl);
close(g);
end;
procedure Run;
var i: integer;
begin
Doc; PP(v,1,n); h := XuLi;
k := 0; Xep(n);
writeln(nl, h, bl, k, nl);
for i := k downto 1 do write(bl, sl[i]);
Ghi;
end;
BEGIN
Run;
write(nl, ' Fini ');readln;
END.
// DevC++: Pages.cpp
#include <fstream>
#include <iostream>
#include <math.h>
using namespace std;
// Data and variables
const char * fn = "pages.inp";
const char * gn = "pages.out";
const int mn = 200;
int n; // so luong tu
int m; // len dong
int k; // so dong can viet

int h; // do hut toi uu


int v[mn]; // len cac tu
int d[mn]; //
int t[mn]; // con tro nguoc
int sl[mn];
// Interface
void Doc();
void PP(int [], int , int);
int XuLi();
void Tinhd(int);
void Xep(int);
void Ghi();
// Implementation
main () {
Doc(); h = XuLi();
k = 0; Xep(n); Ghi();
cout << endl << h << " " << k << endl;
for (int i = k; i > 0; --i) cout << " " << sl[i];
cout << endl << " Fini"; cin.get();
return 0;
}
void Ghi() {
ofstream g(gn);
g << h << " " << k << endl;
for (int i = k; i > 0; --i) g << sl[i] << " ";
g.close();
}
void Tinhd(int i) {
int h = m-v[i]; // cho hut
d[i] = max(h,d[i-1]); t[i] = i;
int hmax;
for (int j = i-1; h >= v[j]; --j) {
h = h - v[j]; hmax = max(h,d[j-1]);
if (d[i] > hmax) { d[i] = hmax; t[i] = j; }
}
}
void Xep(int i) { // xep cac tu tren moi dong
if (t[i] == 0) return;
sl[++k] = i-t[i]+1;
Xep(t[i]-1);
}
int XuLi() {
v[0] = m+1; d[0] = 0; d[1] = m-v[1]; t[1] = 1;
for (int i = 2; i <= n; ++i) Tinhd(i);
return d[n];
}
void Doc() {
ifstream f(fn); f >> n >> m;
cout << n << " " << m;
for (int i = 1; i <= n; ++i) f >> v[i];
f.close();
PP(v,1,n);
}
void PP(int a[], int d, int c) {
cout << endl;
for (int i = d; i <= c; ++i) cout << a[i] << " ";
}

2.11 Xp th

(Bi tng t)
1 2 3 4 5 6 7 8 9 0
1

Dng 1

Dng 2

Dng 3

5
6

O O O

O
O

Bi ton xp th
6

Xp n th nha chi vi chiu di cho trc vo


tm bng rng m n v, gi ng trt t trc sau
sao cho s trng ln nht xt trn tt c cc dng
l nh nht. trng l cha O.
9 S ghi cnh mi th l chiu di ca th .
S ghi ti u mi th l s hiu ca th .

2.12 Xp xe
(Bi tng t)
Ti Hi thi Tin hc tr c n on hc sinh xp hng y ti a im tp trung ch Ban t chc
a xe t n ch cc em i tham quan th . Mi xe c m gh dnh cho mi em mt gh. Cc on
c b tr ln xe theo ng trt t t on s 1 n on s n. Mi xe c th xp vi on lin tip nhau
nhng mi on cn c xp gn trn 1 xe. Sau khi xp y cc on, ngi ta m s gh trng trn
mi xe v cng b s gh trng ln nht h m c. Bit s hc sinh trong mi on, hy tim mt cch
xp xe gi tr h l nh nht.

Chng 3 Cp ghp

Lp cc bi ton xc nh mt tng ng gia hai tp phn t A v B cho trc, th d nh tp A gm cc


em thiu nhi v tp B gm cc mn qu nh trong bi ton Ch Hng di y c gi l cc bi ton cp
ghp v thng c k hiu l f: AB vi ngha l cn xc nh mt nh x, tc l mt php t tng
ng mi phn t i ca tp A vi duy nht mt phn t j ca tp B, f(i) = j. Mt trong cc thut ton gii cc
bi ton ny c tn l thut ton Ghp cp. Thut ton i hi thi gian tnh ton l n.m php so snh trong
n l s phn t (lc lng) ca tp A, m l s phn t ca tp B, n = ||A||, m = ||B||.
Chng ny trnh by thut ton ghp cp v cc bin th ca n.

3.1 Ch Hng
Nhn dp Tt Trung Thu Ch Hng ri Cung Trng mang m mn qu khc nhau m s 1..m n vui Trung
Thu vi n em nh m s 1..n ti mt lng qu. Trc khi Ch Hng pht qu, mi em nh vit ra giy
nhng mn qu m em m c. Yu cu: gip Ch Hng chia cho mi em ng 1 mn qu m em
yu thch.
D liu vo: file vn bn autum.inp
Dng u tin: hai s n m
Dng th i trong s n dng tip theo: k b 1 b2 ... bk - k l s lng qu em i yu thch; b1 b2 ... bk l
m s cc mn qu em i yu thch.
D liu ra: file vn bn autum.out
Dng u tin: v s em nh c nhn qu.
v dng tip theo: mi dng 2 s i b cho bit em i c nhn mn qu b.
Th d,
autum.inp autum.out ngha
C 5 em v 5 mn qu. Em 1 thch 2 mn qu: 1 v 5; em 2 thch 2
5 5
5
mn qu: 2 v 4; em 3 thch 2 mn qu: 1 v 2; em 4 thch 3 mn qu:
2 1 5
1 1
1, 4 v 5; em 5 thch 2 mn qu: 1 v 3.
2 2 4
2 4
2 1 2
3 2
Mt phng n xp em nh qu nh sau: 11; 24; 32; 45;
3 1 4 5
4 5
53.
2 1 3
5 3
Thut ton
Gi s cc phn t ca tp ngun A (cc em nh) c m s t 1 n n v cc phn t ca tp ch B (cc
gi qu) c m s t 1 n m. Sau khi c d liu v thit lp c ma trn 0/1 hai chiu c vi cc phn
t c[i,j] = 1 cho bit em i thch mn qu j v c[i,j] = 0 cho bit em i khng thch qu j. Nhim v t ra l
thit lp mt nh x 11 f t tp ngun vo tp ich, f: A B. Ta s dng phng php chnh dn cc cp
ghp tng thm s cp ghp nh sau.
Ta cng s dng hai mng mt chiu A v B ghi nhn tin trnh chia v nhn qu vi ngha nh sau:
A[i] = j cho bit em i c nhn qu j; B[j] = i cho bit qu j c chia cho em i; A[i] = 0 cho bit
em i cha c chia qu v B[j] = 0 cho bit qu j trong ti qu B cn ri (cha chia cho em no).
Gi s ta chn c qu cho cc em 1, 2, ..., i1. Ta cn xc nh f(i) = j, tc chn mn qu j cho em i.
Nu ta tm ngay c mn qu j B tha ng thi cc iu kin sau:
B[j] = 0: j l mn qu cn trong ti qu B, tc l qu j cha c chia,
c[i,j] = 1, tc l em i thch qu j
th ta t f(i) = j v vic chia qu cho em i xong.
Trng hp ngc li, nu vi mi qu j tha c[i,j] = 1 (em i thch qu j) u c chia cho mt
em t no (B[j] = t 0) th ta phi tin hnh th tc thng lng vi ton b cc em ang gi qu
m bn i thch nh sau:
Tm ngh cc em dang gi qu m bn i thch, t qu vo mt ti ring bn ngoi ti
c ch i vi ngha "s trao 1 mn qu trong ti ny cho bn i";
a nhng em va tr li qu vo mt danh sch st gm cc em cn c u tin tm qu
ngay.
Nh vy, em i s c qu nu nh ta tip tc tm c qu cho mt trong s cc em trong danh sch st ni
trn. Vi mi em trong danh sch st ta li thc hin cc th tc nh lm vi em i ni trn.

Ta cn nh du cc em trong danh sch dm bo rng khng em no xut hin qu hai ln v nh vy


s trnh c vng lp v hn.
Sau mt s bc lp ta s thu c dy
t1 t2 tk1 tk
vi ngha l
em t1 s nhn qu t em t2,
em t2 s nhn qu t em t3,

em tk-1 s nhn qu t em tk.


v s gp mt trong hai tnh hung loi tr nhau sau y:
Tnh hung 1: Ta tm c mt mn qu cho em t k, ngha l vi em tk ta tm c mt mn qu j cn ri
(B[j] = 0) v tk yu thch (c[tk,j] = 1). Ta gi th tc Update(tk, j) thc hin dy cc thao tc chuyn qu
lin hon t em ny cho em kia nh sau:
em tk trao qu qk ca mnh cho bn tk1 nhn qu mi j
em tk1 trao qu qk1 ca mnh cho bn tk-2 nhn qu mi qk t tay bn tk;

em t2 trao qu q2 ca mnh cho bn t1 nhn qu mi q3 t tay bn t3;


em t1 nhn qu j. y chnh l em i m ta cn chia qu.
Ta thu c: f(i) = f(t1) = q2; f(t2) = q3; ...; f(tk) = j v hon thnh vic chia qu cho em i trn c s thng
lng cc em trong dy trn nhng qu cho nhau.
Tnh hung 2: Khng gp tnh hung 1, ngha l, vi mi em trong dy t1, t2,, tk mi mn qu cc em
yu thch u c chia cho em no . Ni cch khc, chin lc nhng qu cho nhau ( nhn qu
khc) khng mang li kt qu. Ta kt lun: "khng th chia qu cho em i".
Do khng th chia c qu cho em i ta tip tc chia qu cho cc em khc.
T chc d liu
Mng nguyn t[1..n], t[j] = i: em j s nhng qu ca mnh cho bn i;
Mng nguyn a[1..n], a[i] = j: em i c chia qu j;
Mng nguyn b[1..m], b[j] = i: qu j ang c trong tay em i. rng a[b[j]] = j v b[a[i]] = i;
Mng nguyn st[1..n]: danh sch cc em tm tr li qu v ang cn c u tin nhn qu mi.
Bin nguyn p: tr ti ngn trn cng ca stack st.
Mng nguyn 2 chiu nh phn c[1..n,1..m], c[i][j] = 1 khi v ch khi em i thch qu j;
Hm Xep(i): chia qu cho bn i; Xep(i) = 1 nu tm c mt cch chia, ngc li, khi khng tm
c Xep = 0.
Hm Par thc hin ghp cp cho cc em theo th t t 1 n n.
(* Autum.pas *)
uses crt;
const fn = 'autum.inp'; gn = 'autum.out';
bl = #32; nl = #13#10; mn = 201;
type mi1 = array[0..mn] of integer;
mb2 = array[0..mn,0..mn] of byte;
var n, m: integer; { n - so nguoi; m - so qua }
a, b: mi1;
t: mi1;
st: mi1; p: integer;
c: mb2;
f,g: text; {f: input file; g: otput file }
procedure Doc;
var i,j,k,q: integer;
begin
assign(f,fn); reset(f); read(f,n,m);
fillchar(c,sizeof(c),0);
for i := 1 to n do
begin
read(f,k);
for j := 1 to k do begin read(f,q); c[i][q] := 1 end;
end;
close(f);
end;
procedure Print;
var i,j: integer;

begin
writeln(nl,n,bl,m);
for i := 1 to n do
begin
for j := 1 to m do write(c[i,j]);
writeln;
end;
end;
procedure Update(i,j: integer);
var q: integer;
begin
repeat
q := a[i]; { i b qa q }
a[i] := j; b[j] := i; { nhn qu j }
j := q;
i := t[i]; { chuyn qua ngi trc }
until q = 0;
end;
function Xep(i: integer): integer;
var j: integer;
begin
Xep := 1;
p := 0; inc(p); st[p] := i; { np st }
fillchar(t, sizeof(t),0); t[i] := i;
while p > 0 do
begin
i := st[p]; dec(p); { Ly ngn st }
for j := 1 to m do
if c[i,j] = 1 then { i thch qa j }
begin
if b[j] = 0 then { qa j cha chia }
begin Update(i,j); exit end
else if t[b[j]] = 0 { b[j] cha c trong st }
then begin inc(p); st[p] := b[j]; t[b[j]] := i end;
end;
end;
Xep := 0;
end;
procedure Ghi(v: integer);
var i: integer;
begin
assign(g,gn); rewrite(g);
writeln(g,v);
for i := 1 to n do
if a[i] > 0 then writeln(g,i,bl,a[i]);
close(g);
end;
procedure Par; { Ghep cap }
var i,v: integer;
begin
Doc; Print; v := 0;
fillchar(a, sizeof(a),0); b := a;
for i := 1 to n do v := v + Xep(i);
Ghi(v);
end;
BEGIN
Par;
write(nl,' Fini '); readln;
END.
// DevC++: Autum.cpp
#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 = "autum.inp";
const char * gn = "autum.out";
const int mn = 201; // so nguoi va so qua toi da
int a[mn]; // a[i] = j: em i nhan qua j
int b[mn]; // b[j] = i: qua j trong tay em i
int t[mn]; // t[j] = i : em j nhuong qua cho ban i
int c[mn][mn]; // c[i][j] = 1: i thich qua j
int n; // so em nho
int m; // so qua
int st[mn]; // stack
int p; // con tro stack
// P R O T O T Y P E S
int main();
void Doc();
void Print();
int Par();
int Xep(int);
void Update(int, int);
void PrintArray(int [], int , int );
void Ghi(int);
// I M P L E M E N T A T I O N
int main() {
Doc();
Print();
int v = Par();
Ghi(v);
cout << endl << "Xep duoc " << v << " em.";
PrintArray(a,1,n);
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void Ghi(int v) {
ofstream g(gn);
g << v << endl;
for (int i = 1; i <= n; ++i)
if (a[i] > 0) g << i << " " << a[i] << endl;
g.close();
}
void PrintArray(int a[], int d, int c) {
int i;
cout << endl;
for (i = d; i <= c; ++i) cout << a[i] << " ";
}
void Update(int i, int j){
int c;
do {
c = a[i]; // i bo qua c xuong
a[i] = j; b[j] = i; // i nhan qua moi j
i = t[i]; j = c; // chuyen qua nguoi khac
} while (c > 0);
}
int Xep(int i) { // tim qua cho em i
memset(t, 0, sizeof(t));
int j;
p = 0; st[++p] = i; t[i] = i;
while(p > 0) {
i = st[p--]; // lay ngon stack
for (j = 1; j <= m; ++j) { // duyet cac mon qua
if (c[i][j] > 0) { // i thich qua j

if (b[j] == 0) { // qua j chua chia


Update(i,j); return 1;
}
if (t[b[j]] == 0) { //b[j] chua co trong danh sach
st[++p] = b[j]; t[b[j]] = i; // nap
}
}
}
}
return 0; // Khong chon duoc qua cho em i
}
int Par(){ // Cap ghep
int v = 0, i;
memset(a,0,sizeof(a)); memset(b,0,sizeof(b));
for (i = 1; i <= n; ++i) v += Xep(i);
return v;
}
void Print() { // Hien thi ma tran c
cout << endl << n << " " << m << endl;
int i,j;
for (i = 1; i <= n; ++i){
for (j = 1; j <= m; ++j)
cout << c[i][j] << " ";
cout << endl;
}
}
void Doc(){
memset(c,sizeof(c),0);
ifstream f(fn);
f >> n >> m;
int i,j,k,r;
for (i = 1; i <= n; ++i) {
f >> k;
for (r = 1; r <= k; ++r) {
f >> j ; c[i][j] = 1;
}
}
f.close();
}
Nhn xt Ta c th dng ngn xp hay hng i trong bi ny kt qu khng ph thuc vo trt t duyt.

3.2 Domino

Cho li n v gm n dng v m ct. Cc trong li c gn m s 1, 2, ... , n m theo trt t t dng


trn xung dng di, trn mi dng tnh t tri qua phi. Ngi ta t v vch ngn gia hai k cnh
nhau. Hy tm cch t nhiu nht k qun domino, mi qun gm hai k cnh nhau trn li v khng c
vch ngn gia.
domino.inp
4 5 8
2 3
4 5
6 7
9 10
10 15
7 12
19 20
13 18

domino.out
10
1 2
3 4
5 10
6 11
7 8
9 14
12 13
15 20
16 17
18 19

D liu
Input file: Text file domino.inp.
Dng u ti`n: 3 s n s dng, m s ct, v s vch
ngn.
Tip n l v dng, mi dng 2 s a b cho bit vch ngn t
gia hai ny.
Output file: Text file domino.out.
Dng u tin k s qun
1
2
3
4
5
domino ti a t c trn li.
6
7
8
9
10
Tip n l k dng, mi dng 2
11 12 13 14 15
s x y cho bit s hiu ca 2 k
cnh nhau to thnh mt qun
16 17 18 19 20
domino.

Thut ton
Bi ny c hai im khc vi dng bi cp ghp truyn thng. Th nht l ghp cp c thc hin t mt
tp A vi chnh n: f: A A. Th hai, mi s trong tp A ch c th ghp ti a vi 4 s trong cc k
cnh n m ta tm gi l s k. Th d, 8 c 4 s k theo th t tri, phi v trn, di l 7, 9 v 3, 13.
Cc s ngoi ri v cc s c vch ngn cn c t bn hn. Th d, 20 c ng 1 bn.
Khi c d liu ta xc nh ngay cho mi s i trong bng bn s k v ghi vo mng ke vi ngha nh sau
ke[i][j] = 1 khi v ch khi i c s k ti v tr j; j = 1, 2, 3, 4. Nu i c vch ngn phi th i s mt bn k
phi. Tng t, nu i c vch ngn di th i s mt bn k di. Ngoi ra, d hiu rng cc s trn dng 1
th khng c s k trn, cc s trn dng n th khng c s k di. Tng t, cc s trn ct 1 th khng c
s k tri, cc s trn ct m th khng c s k phi.
Nhc li rng ta ch cn s dng mt mng a vi ngha a[i] = j, ng thi a[j] = i cho bit s i chn s k j
ghp thnh 1 qun domino. Ni cch khc nu ta xp c f(i) = j th ta phi gn a[i] = j v a[j] = i.
Tip n ta thc hin th tc Xep(i) cho mi s cha c ghp cp (a[i] = 0) v cha l bn ca bt k s
no (b[i] = 0).
Khi ghi kt qu ra file ta lu l hai cp (i , a[i] = j) v (j, a[j] = i) thc ra ch to thnh mt qun domino
duy nht, do ta ch cn ghi mt trong hai cp . Ta chn cp i < a[i] trnh trng hp khng xp
c cho s i, v khi a[i] = 0 tc l i > a[i].
(* Domino.pas *)
uses crt;
const maxmn = 201; fn = 'domino.inp'; gn = 'domino.out';
bl = #32; nl = #13#10; phai = 1; trai = 2; tren = 3; duoi = 4;
type mi1 = array[0..maxmn] of integer;
var n: integer; { so dong }
m: integer; { so cot }
nm: integer;{ nm = n.m }
f,g: text;
ke: array[0..maxmn,phai..duoi] of Boolean;
st: mi1; { stack } p: integer; { ngon st }
a, t: mi1;
procedure Doc;
var i, j, k, v, t: integer;
begin
fillchar(ke,sizeof(ke),true);
assign(f,fn); reset(f);
readln(f,n,m,v); { v - so vach ngan }
nm := n*m;
{ dong 1 va dong n } k := (n-1)*m;
for j := 1 to m do
begin
ke[j, tren] := false; ke[j+k, duoi] := false;
end;

j := 1; { cot 1 va cot m }
for i := 1 to n do
begin
ke[j , trai] := false; j := j + m; ke[j-1, phai] :=
end;
for k := 1 to v do
begin
readln(f,i,j);
if i > j then begin t := i; i := j; j := t end; { i
if i = j-1 then ke[i,phai] := false else ke[i,duoi]
end;
close(f);
end;
procedure Update(i,j: integer);
var q: integer;
begin
repeat
q := a[i]; { i bo so q }
a[i] := j; a[j] := i; { de nhan so j }
j := q;
i := t[i]; { chuyen qua so truoc }
until q = 0;
end;
function Xep(i: integer): integer;
var j, k: integer;
begin
Xep := 1;
p := 0; inc(p); st[p] := i; { nap st }
fillchar(t, sizeof(t),0); t[i] := i;
while p > 0 do
begin
i := st[p]; dec(p); { Lay ngon st }
for k := 1 to 4 do
if ke[i,k] then { i co o ke }
begin
case k of
tren: j := i - m;
duoi: j := i + m;
phai: j := i + 1;
trai: j := i - 1;
end;
if a[j] = 0 then { j chua bi chiem }
begin Update(i,j); exit end
else if t[a[j]] = 0 { a[j] chua co trong st }
then begin inc(p); st[p] := a[j]; t[a[j]] := i
end;
end;
Xep := 0;
end;
function Par: integer;
var i, v: integer;
begin
fillchar(a,sizeof(a),0); v := 0;
for i := 1 to nm do
if a[i] = 0 then v := v + Xep(i);
par := v;
end;
procedure Ghi(k: integer);
var i: integer;
begin
assign(g,gn); rewrite(g);
writeln(g, k);
for i := 1 to nm do

false;

< j }
:= false;

end;

if i < a[i] then


writeln(g,i,bl,a[i]);
close(g);
end;
procedure Run;
var k: integer;
begin
Doc; k := Par; Ghi(k);
end;
BEGIN
Run;
writeln(nl,' Fini'); readln;
END.
// DevC++: Domino.cpp
#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 = "domino.inp";
const char * gn = "domino.out";
const int Maxmn = 201; // tich max n.m
const int phai = 0;
const int duoi = 1;
const int tren = 2;
const int trai = 3;
int a[Maxmn]; // a[i] = j, a[j] = i: i chon j
int t[Maxmn]; // t[j] = i : j nhuong cho i
bool ke[Maxmn][4]; // moi so co toi da 4 so ke
int n; // so dong
int m; // so cot
int nm;
int st[Maxmn]; // stack
int p; // con tro stack
// P R O T O T Y P E S
int main();
void Doc();
int Par();
int Xep(int);
void Update(int, int);
void Ghi(int);
// I M P L E M E N T A T I O N
int main() {
Doc();
int k = Par();
Ghi(k);
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void Ghi(int k) {
ofstream g(gn);
g << k << endl;
for (int i = 1; i <= nm; ++i)
if (i < a[i])
g << i << " " << a[i] << endl;
g.close();
}
void Update(int i, int j){
int c;
do {
c = a[i]; // i bo c xuong
a[i] = j; a[j] = i; // i nhan so moi j

i = t[i]; j = c; // chuyen qua so khac


} while (c > 0);
}
int Xep(int i) { // tim so ghep voi i
memset(t, 0, sizeof(t));
int j, k;
p = 0; st[++p] = i; t[i] = i;
while(p > 0) {
i = st[p--]; // lay ngon stack
for (j = 0; j < 4; ++j) { // duyet cac o ke
if (ke[i][j] > 0) { // co o ke
switch(j) {
case tren: k = i-m; break;
case duoi: k = i+m; break;
case phai: k = i+1; break;
case trai: k = i-1; break;
}
if (a[k] == 0) { // o k chua bi chiem
Update(i,k); return 1;
}
if (t[a[k]] == 0) { // a[k] chua co trong danh sach
st[++p] = a[k]; t[a[k]] = i; // nap
}
}
}
}
return 0; // Khong chon duoc cap ghep cho i
}
int Par(){ // Cap ghep
int v = 0, i;
memset(a,0,sizeof(a));
for (i = 1; i <= nm; ++i)
if (a[i]==0) v += Xep(i);
return v;
}
void Doc(){
int i, j, k, r, v; // so vach ngan
int n1, m1,ij;
ifstream f(fn);
f >> n >> m >> v; nm = n*m;
n1 = n-1; m1 = m-1;
memset(ke,1, sizeof(ke));
// duyet cac o trong
for (j = (n-1)*m, i = 1; i <= m; ++i)
ke[i][tren] = ke[i+j][duoi] = 0;
for (j = m-1, i = m; i <= nm; i += m)
ke[i-j][trai] = ke[i][phai] = 0;
for (i = 0; i < v; ++i) {
f >> k >> r;
if (k > r) { j = k; k = r; r = j; } // k < r
if (r == k+1) ke[k][phai] = ke[r][trai] = 0;
else ke[k][duoi] = ke[r][tren] = 0;
}
f.close();
}

3.3 Thm him


Trng A v trng B u c n hc sinh (HS) tham gia tr chi Thm him Cung Trng vi n xe t hnh,
mi xe ch c 2 ngi c nhim v kho cu mt ti khoa hc v hot ng ti mt vng ring trn
Cung Trng vi mt ch c th ghi trn xe . Sau khi xem bn hng dn v trnh din th ca cc xe
t hnh, mi HS chn mt s xe. Ban t chc (BTC) cn chia cc em thnh cc nhm, mi nhm 2 bn s

lm vic trn mt xe, mt bn ca trng A, mt bn ca trng B sao cho 2 bn trn cng mt xe th cng
quan tm n ch chung. Hy gip BTC sp xp sao cho nhiu ch nht c thc hin.
D li vo: Text file Discover.inp.
Dng u tin: s t nhin n
Dng th i trong s n dng tip theo c dng: k c1 c2 ... ck trong k l s lng xe HS i ca trng
A chn, cc s tip theo l m s ca cc xe ng thi l m s ca ti m bn chn.
Dng th i trong s n dng tip theo l thng tin ca trng B c cu trc tng t nh ca trng
A.
D liu ra: Text file Discover.out gm n dng, mi dng 2 hc sinh: i ca trng A, j ca trng B cho bit
i v j to thnh mt nhm do cng chn mt xe. D liu trn cng dng cch nhau qua du cch. Bi ton
lun lun c nghim.

Discover.inp
5
3 3 1 4
2 2 3
3 4 2 1
2 1 3
3 5 4 2
3 2 3 1
3 1 4 3
2 5 2
3 4 2 1
3 3 1 2

Discover.out
1 1
2 5
4 2
3 4
5 3

ngha
Trng A: 5 HS, trng B: 5 HS, 5 xe = 5 ch .
Kt qu (HS trng A, HS Trng B): (1,1), (2,5), (4,2), (3,4),
(5,3)

1
xe
1
xe
2
xe
3
xe
4
xe
5

Hc sinh trng A
2
3
4
5

1
2

Hc sinh trng B
2
3
4
5

3
4

4
5

Thut ton
Ta thc hin hai ln ghp cp Xe-Trng A v Xe-Trng B. Sau ln ghp th nht ta thu c kt qu ghi
trong mng a[1..n] trong a[i] = j cho bit xe i s ch bn j ca trng A. Sau ln ghp th hai ta li thu
c kt qu ghi trong mng b[1..n] trong b[i] = k cho bit xe i s ch bn k ca trng B. Tng hp li
ta c mi xe i s ch 2 bn, bn a[i] ca trng A v bn b[i] ca trng B, i = 1..n.
Khung chng trnh khi s nh sau:
1. M file input f "Discover.inp";
2. c s n;
A
B
3. c d liu ca trng A vo mng 2 chiu c, c[i][j] = 1 khi v ch khi xe i
10110 11011
c HS j ca trng A chn;
01101 10111
4. Gi th tc Par(a) ghp cp Xe A cho HS trng A. Kt qu a[i] = j cho
11010 11001
bit xe i s ch HS i ca trng A, i = 1..n;
10101 01010
5. c tip d liu ca trng B vo mng 2 chiu c, c[i][k] = 1 khi v ch khi
00001 00100
xe i c HS k ca trng B chn;
6. Gi th tc Par(b) ghp cp Xe B cho HS trng B. Kt qu b[i] = k cho bit xe i s ch HS k
ca trng B, i = 1..n;
7. Ghi cc cp a[i], b[i], i = 1..n vo file output;
8. ng cc files input v output.
Bn lu , vi th d cho, sau khi c n dng d liu ca trng A bn phi thu c kt qu trong
mng c nh mnh A trong bng. Tng t, sau khi c tip n dng d liu ca trng B bn phi thu
c kt qu trong mng c nh mnh B trong bng.
(* Pas: Discover *)
uses crt;
const
fn = 'Discover.inp'; gn = 'Discover.out';
mn = 201; bl = #32; nl = #13#10;
type mi1 = array[0..mn] of integer;
mb2 = array[0..mn,0..mn] of byte;
var
f,g: text;
n: integer; { so HS = so xe = so de tai }
c: mb2; { c[i,j] = 1 khi va chi khi hs j chon xe i }
a, b: mi1; { xep xe truong a, b }
t, x: mi1; { t - tro truoc }
st: mi1; { stack }
p: integer; { ngon st }
procedure XemC;

var i,j: integer;


begin
write(nl,n);
for i := 1 to n do
begin
writeln;
for j := 1 to n do write(c[i,j]);
end;
end;
{ xep lien hoan, xe i, hs j }
procedure Update(var a: mi1; i, j: integer);
var c: integer;
begin
repeat
c := a[i]; { hs c roi xe i }
a[i] := j; x[j] := i; { hs j len xe i }
j := c; i := t[i]; { xet hs tiep }
until c = 0;
end;
function XepXe(var a: mi1; i: integer): integer; { xep xe i }
var j: integer;
begin
XepXe := 1; p := 1; st[p] := i;
fillchar(t, sizeof(t),0); t[i] := i;
while (p > 0) do
begin
i := st[p]; dec(p); { xe i }
for j := 1 to n do { hs j }
if (c[i,j] = 1) then { hs j chon xe i }
begin
if x[j] = 0 { hs j chua len xe } then
begin Update(a,i,j); exit end; { xep duoc xe i }
{ Nap x[j] vao st }
if t[x[j]] = 0 { x[j] chua duoc nap }
then begin inc(p); st[p] := x[j]; t[x[j]] := i end;
end;
end;
XepXe := 0; { kho xep duoc xe i }
end;
function Par(var a: mi1): integer;
var i, k: integer;
begin
k := 0; { so xe da xep duoc }
fillchar(a, sizeof(a),0); x := a;
for i := 1 to n do k := k + XepXe(a,i);
Par := k;
end;
procedure Doc;
var soxe, hs, xe, j: integer;
begin
fillchar(c,sizeof(c),0);
for hs := 1 to n do
begin
read(f,soxe);
for j := 1 to soxe do { Hs chon xe }
begin read(f,xe); c[xe,hs] := 1 end;
end;
end;
procedure Ghi;
var i: integer;
begin
assign(g,gn); rewrite(g);

for i := 1 to n do writeln(g,a[i],bl,b[i]);
close(g); close(f);
end;
procedure Run;
var i: integer;
begin
assign(f,fn); reset(f); readln(f,n);
Doc; Par(a);
Doc; Par(b);
Ghi;
end;
BEGIN
Run;
write(nl,nl,' Fini'); readln;
END.
// DevC++: Discover.cpp
#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 = "Discover.inp";
const char * gn = "Discover.out";
const int mn = 501;
int a[mn]; // a[i] xe i cho HS truong A
int b[mn]; // b[i] xe i cho HS truong B
int x[mn];
int t[mn];
int c[mn][mn]; // c[i][j] = 1 xe i duoc HS j chon
int n; // so hoc sinh cua moi truong A, B; so xe
int st[mn]; // stack
int p; // ngon stack
ifstream f(fn); // mo san input file
// P R O T O T Y P E S
int main();
void Doc();
void Print();
int Par(int []);
int Xep(int [], int);
void Update(int [], int, int);
void PrintArray(int [], int , int );
void Ghi();
// I M P L E M E N T A T I O N
int main() {
f >> n; Doc(); Print(); Par(a);
cout << endl << " Xep xong truong A: "; PrintArray(a,1,n);
Doc(); f.close(); Par(b);
cout << endl << " Xep xong truong B: "; PrintArray(b,1,n);
Ghi();
cout << endl << " Fini "; cinget();
return 0;
}
void Ghi() {
ofstream g(gn);
for (int xe = 1; xe <= n; ++xe)
g << a[xe] << " " << b[xe] << endl;
g.close();
}
void PrintArray(int a[], int d, int c) { // hien thi mang a[d..c]

int i;
cout << endl;
for (i = d; i <= c; ++i)

cout << a[i] << " ";


}
void Update(int a[], int i, int j){
int xe;
do {
xe = a[i]; // HS i roi xe
a[i] = j; x[j] = i; // vao xe j
i = t[i]; j = xe;
} while (xe > 0);
}
int Xep(int a[], int i) { // xep HS vao xe i
memset(t, 0, sizeof(t));
int j;
p = 0; st[++p] = i; t[i] = i;
while(p > 0){
i = st[p--]; // lay ngon st, xe i
for (j = 1; j <= n; ++j) { // duyet cac HS j
if ((c[i][j] == 1)) { // xe i co the xep HS j
if (x[j] == 0) { // HS j chua duoc xep
Update(a,i,j); return 1;
}
if (t[x[j]] == 0) { // xe x[j] chua nap
st[++p] = x[j]; t[x[j]] = i;
}
} // if
} // for
} // while
return 0; // Khong xep duoc cho HS i
}
int Par(int a[]) {
int d = 0, i;
memset(a,0,sizeof(a)); memset(x,0,sizeof(b));
for (i = 1; i <= n; ++i) d += Xep(a,i);
return d;
}
void Print(){
cout << endl << n << endl;
int i,j;
for (i = 1; i <= n; ++i)
{
for (j = 1; j <= n; ++j)
cout << c[i][j] << " ";
cout << endl;
}
}
void Doc() {
memset(c,0,sizeof(c));
int hs, xe, soxe, r;
for (hs = 1; hs <= n; ++hs) { // truong A
f >> soxe;
for (r = 1; r <= soxe; ++r)
{ f >> xe ; c[xe][hs] = 1; }
}
}

3.4 Show
Nhm n hc sinh (HS) tham gia trnh din phn mm. Mi em c trnh by ring sn phm ca mnh
trc Ban gim kho (BGK) trong thi hn 30 pht. BGK lm vic trong m ngy, ngy th i c th nhn v i
HS. Trong bn ng k mi HS ghi kh nng c th trnh din phn mm ca mnh vo nhng ngy no.
Hy sp lch cc HS c trnh din theo ng nguyn vng.
D liu vo: Text file show.inp

Dng u tin: hai s n m.


Dng th hai: cc gi tr v1 v2 vm
Dng th i trong s n dng tip theo: k u1 u2 uk
trong k l s ngy HS i chn, cc uj l nhng ngy c th HS i chn.
D liu ra: Text file show.out gm m dng,
dng th i cho bit ngy th i BGK duyt trnh din
ca nhng HS no.
D liu trn cng dng cch nhau qua du cch
show.inp
5 3
2 2 1
1 2
2 1 3
2 2 3
1 1
1 1

show.out
4 5
1 3
2

ngha
5 hc sinh, 3 ngy trnh din
Ngy 1
Ngy 2

HS 1

HS 2

HS 3

HS 4

HS 5

Ngy 3

Thut ton
Bi ny kh d gii nu ta bit cch bin i ngy thnh phin theo tng nh sau. Ta hiu mi lt trnh
din ca mt HS l mt phin.

Phin

Ngy 1

Ngy 2

Ngy 3

i ngy thnh phin:

P1

P3

P4

P5

Nu trong mt ngy no BGK ch chm c cho k HS th


ngy c k phin. nh s tun t cc phin 1, 2, ...

Ngy 1 c 2 phin 1 v 2; ngy 2 c 2 phin 3 v 4; ngy 3


c 1 phin 5.

Ngy ng k ca HS cng c i theo. HS 1 ng k ngy


1 s i thnh ng k 2 phin 1 v 2; HS 2 ng k 2 ngy 1
v 3 s i thnh ng k 3 phin 1, 2 v 5,...

P2

HS 1
HS 2

HS 3
HS 4

HS 5

Khi c d liu ta ghi vo mng s, s[i] cho bit s hiu phin ca cui mi ngy. Vi th d trn, sa khi c
d liu bn phi tnh c s phin sp = 5 v s[0..3] = (0,2,4,5). Ngy th nht kt thc ti phin 2; ngy
th hai kt thc ti phin 4 v ngy cui cng, ngy th m = 3 kt thc ti phin 5.
Sau bn t chc mng 2 chiu c, c[i,j] cho bit HS i thch trnh din ti phin j. Ch rng HS ng k 1
ngy c th sinh ra nhiu phin ty thuc vo ngy hm c my phin. Phin chnh l s HS c BGK
cho php trnh din trong ngy .
Sau khi thc hin th tc cp ghp nh cc bi trc, bn cn duyt li kt qu i phin thnh ngy.
(* Show.pas *)
uses crt;
(* D A T A
A N D
V A R I A B L E S *)
const fn = 'show.inp'; gn = 'show.out';
mn = 101; bl = #32; nl = #13#10;
type mi1 = array[0..mn] of integer;
mb2 = array[0..mn,0..mn] of byte;
var
n, m: integer; { n - so hs; m - so ngay }
s: mi1; { s[i] - phien cuoi cua ngay i }
a,b: mi1;
c: mb2; { c[i,j] = 1 khi va chi khi hs i chon phien j }
t, st: mi1; { stack st }
p: integer; { ngon st }
sp: integer; { so phien lam viec cua BGK }
f,g: text;
(* I M P L E M E N T A T I O N *)
function ToNgay(p: integer): integer; { Doi Phien p -> ngay }
var ng: integer;
begin
ng := 1;
while (p > s[ng]) do inc(ng);
ToNgay := ng
end;
procedure Ghi;
var i,j,ng: integer;
begin
fillchar(c,sizeof(c),0);
for i := 1 to n do
if (a[i] > 0) then begin ng := ToNgay(a[i]); c[ng,i] := 1;
end;
{ Xep ngay cho hs i }
assign(g,gn); rewrite(g);
for i := 1 to m do { Duyet c theo ngay i }
begin
for j := 1 to n do { Hs j }
if (c[i,j] > 0) then write(g,j,bl);
writeln(g);
end;
close(g);

end;
procedure Update(i,j: integer);
var c: integer;
begin
repeat
c := a[i];
a[i] := j; b[j] := i;
i := t[i]; j := c;
until c = 0;
end;
function XepHs(i: integer): integer;
var j: integer;
begin
XepHs := 1; fillchar(t,sizeof(t),0);
p := 1 ; st[p] := i; t[i] := i;
while(p > 0) do
begin
i := st[p]; dec(p); { Lay ngon st, xep phien cho hs i }
for j := 1 to sp do { duyet cac phien }
if c[i,j] = 1 then { hs i chon phien j }
begin
if b[j] = 0 then { Phien j con roi }
begin Update(i,j); exit end;
if (t[b[j]] = 0) then { hs b[j] chua nap }
begin inc(p); st[p] := b[j]; t[b[j]] := i; end;
end;
end;
XepHs := 0; { Ko xep duoc phien cho hs i }
end;
function Par: integer;
var i, d: integer;
begin
fillchar(a, sizeof(a),0); b := a;
d := 0;
for i := 1 to n do d := d + XepHs(i);
Par := d;
end;
procedure Doc;
var i,j,k,r,q: integer;
begin
fillchar(c,sizeof(c),0);
assign(f,fn); reset(f); readln(f, n, m);
s[0] := 0;
for i := 1 to m do { m ngay lam viec }
begin
read(f,r); { so phien trong ngay i }
s[i] := s[i-1] + r; { s[i] - phien cuoi cua ngay i }
end;
sp := s[m]; { Tong so phien }
for i := 1 to n do { xet nguyen vong cua hs i }
begin
read(f,k); { so ngay hs i chon }
for r := 1 to k do
begin
read(f,j); { cac phien trong ngay j }
for q := s[j-1]+1 to s[j] do c[i][q] := 1; { hs i chon
phien q }
end
end;
close(f);
end;
procedure PA(var a: mi1; d,c: integer); { Print array a[d..c] }
var i: integer;

begin for i := d to c do write(a[i],bl); end;


procedure Xem;
var i,j: integer;
begin
write(nl,n,bl,m,nl);
for i := 1 to n do
begin
writeln;
for j := 1 to sp do write(c[i,j]);
end;
end;
BEGIN
Doc; Xem; writeln(nl,' Xep duoc: ',Par);
Ghi;
write(nl,' Fini '); readln;
END.
// DevC++: Show.cpp
#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 = "show.inp";
const char * gn = "show.out";
const int mn = 101;
int a[mn];
int b[mn];
int t[mn];
int c[mn][mn];// c[i][j] = 1 khi va chi khi HS i dang ki phien j
int n; // so hoc sinh
int m; // so ngay lam vic cua BGK
int sp; // so phien lam viec cua BGK
int s[mn]; // s[i] - ma so phien cuoi cua ngay i
int st[mn]; // stack
int p; // ngon stack
// P R O T O T Y P E S
int main();
void Doc();
int Par();
int Xep(int);
void Update(int, int);
void Ghi();
int ToNgay(int);
// I M P L E M E N T A T I O N
int main() {
Doc(); Par(); Ghi();
cout << endl << " fini "; cin.get();
return 0;
}
int ToNgay(int p) { // Phien -> ngay
int ng = 1;
while (p > s[ng]) ng++;
return ng;
}
void Ghi() {
int i,j;
memset(c,0,sizeof(c));
for (i = 1; i <= n; ++i) // hs i
if (a[i] > 0) c[ToNgay(a[i])][i] = 1;
// c[j][i] = 1 neu hs i duoc xep cho ngay j
ofstream g(gn);
for (int i = 1; i <= m; ++i){ // ngay i
for (j = 1; j <= n; ++j) // hs j

if (c[i][j] > 0) g << j << " ";


g << endl;
}
g.close();
}
void Update(int i, int j){
int c;
do {
c = a[i];
a[i] = j; b[j] = i;
i = t[i]; j = c;
} while (c > 0);
}
int Xep(int i) { // xep cho HS i
memset(t, 0, sizeof(t));
int j;
p = 0; st[++p] = i; t[i] = i;
while(p > 0){
i = st[p--];
for (j = 1; j <= sp; ++j) { // duyet cac buoi
if (c[i][j] > 0) { // i chon j
if (b[j] == 0) { // j con roi
Update(i,j); return 1;
}
if (t[b[j]] == 0) { // b[j] chua nap
st[++p] = b[j]; t[b[j]] = i;
}
}// if
} // for
} // while
return 0; // Khong xep duoc cho HS i
}
int Par(){
int d = 0, i;
memset(a,0,sizeof(a)); memset(b,0,sizeof(b));
for (i = 1; i <= n; ++i) d += Xep(i);
return d;
}
void Doc(){
memset(c,0,sizeof(c));
ifstream f(fn);
f >> n >> m; // n - so hs; m - so ngay
int i,j,k,r,q;
s[0] = 0;
for (i = 1; i <= m; ++i) {
f >> r; // so phien trong ngay i
s[i] = s[i-1] + r; // s[i] - phien cuoi cua ngay i
}
sp = s[m];
for (i = 1; i <= n; ++i){ // nguyen vong cua hs i
f >> k; // so ngay hs i chon
for (r = 1; r <= k; ++r){
f >> j ; // HS i chon ngay j
for (q = s[j-1]+1; q <= s[j]; ++q) // duyet theo phien
c[i][q] = 1;
}
}
f.close();
}

3.5 Cp ghp cc i: Ch Hng 2


Ni dung ging bi cp ghp vi mt thay i nh sau: c[i][j] = v cho bit em i yu thch mn qu j vi
mc vi, 0 vi 10. Yu cu ghp cp sao cho tng yu thch t max.
autum2.inp
5 5
1 2 3 10 5
1 2 3 4 11
12 2 3 4 5
1 13 3 4 5
1 2 14 4 5

autum2.out
60
1 4
2 5
3 1
4 2
5 3

Input text file: autum2.inp


Dng u tin: hai s n v m, trong n l s em nh; m l s
qu. Tip n l n dng ca ma trn c[1..n,1..m], mi dng m
s; m n.
Output text file: autum2.out
Dng u tin: gi tr max tng yu thch t c theo
phng n ghp cp chn. Tip n l n dng, mi dng 2
s i j cho bit em i nhn qu j.

Thut ton
Ta qun l mt gi tr dmax l gi tr gia tng nhiu nht trong cc phng n xp qu cho em i. Th d, sau
khi xp qu cho i1 em u tin ta chuyn qua xp qu cho em i. Gi s ta c 2 phng n xp qu cho
em i. Phng n th nht c th tng gi tr dmax ln thm v1 n v, phng n th hai c th tng gi tr
dmax ln thm v2 > v1 n v. Ta s chn phng n th hai. thc hin iu ny ta cn lu my gi tr
sau y.

a[i] l qu em i hin gi trn tay, b[j] l em ang gi qu j. Ta bit b[a[i]] = i v a[b[j]] = j,


ngoi ra, nu em i cha c chia qu th ta t a[i] = 0, v nu mn qu j cha c chia cho em
no th b[j] = 0.

c[i,j] l yu thch ca em i i vi mn qu j m ta tm gi l gi tr ca mn qu j i vi em i
hay vn tt l gi tr. rng cng mt mn qu j nhng em i s nh gi khc vi em k, tc l
ni chung c[i,j] c[k,j].

Khc vi phng php ghp cp khng phn bit mc yu thch trc kia, mi khi tm c mt dy
lin hon em t1 nhn qu t em t2, t2 nhn qu t em t3, ..., tk s nhn mn qu q cha chia
i = t1 t2 tk1 tk = j

(*)

th ta nh gi xem nu quyt nh kt thc th tc Xep(i) bng cch thc hin dy lin hon (*) th gi tr
gia tng dmax ca phng n ny l bao nhiu v cp nht gi tr .
Gi d l gi tr gia tng ca phng n chia qu. Mi khi em j nhng qu a[j] ca mnh cho bn i nhn
qu mi q th gi tr ca phng n s thay i nh sau:

d gim mt lng c[j,a[j]] khi em j t qu a[j] xung;

d tng mt lng c[j,q] khi em j nhn qu mi q;

d tng mt lng c[i,a[j]] khi em i nhn qu a[j] t bn j.

Tng hp li, gi tr gia tng ca vic em j nhng qu cho em i nhn qu mi q s l c[j,q] + c[i,a[j]]
c[i,a[j]]. Ta c d := d + c[j,q] + c[i,a[j]] c[i,a[j]].
K hiu d(j) l gi tr gia tng ca phng n khi em j c a vo danh sch nhng qu. Phng n ny
bt u bng vic tm qu cho em i, do d(i) = 0. Mi khi a j vo danh sch nhng qu cho k ta tnh
c d(j) = d(k) + c[k,a[j]] c[k,a[j]].
Gi s ta quyt nh kt thc vic tm qu cho em i, tc l kt thc th tc xt ti dy (*). Khi do em j
cui cng trong dy nhn qu mi l q th gi tr gia tng ca phng n s c cng thm mt lng
c[j,q] v bng d(j) + c[j,q]. Ta so snh i lng ny vi dmax ghi nhn tnh hung ti u.
(* Autum2.pas *)
uses crt;
const fn = 'autum2.inp'; gn = 'autum2.out';
mn = 201; { so nguoi va so qua toi da }
bl = #32; nl = #13#10;
type mi1 = array[0..mn] of integer;
mb2 = array[0..mn,0..mn] of byte;
var a: mi1; { a[i] = j: em i nhan qua j }
b: mi1; { b[j] = i: qua j trong tay em i }
t: mi1; { t[j] = i : em j nhuong qua cho ban i }

c: mb2; { c[i][j] = 1: i thich qua j }


d: mi1; { d[j]: gia tri gia tang tich luy den em j }
n: integer; { so em nho }
m: integer; { so qua }
st: mi1; { stack }
p: integer; { tro ngon st }
imax, jmax, dmax: integer;
procedure Ghi(v: integer);
var vmax, i: integer;
g: text;
begin
vmax := 0;
for i := 1 to n do
if (a[i] > 0) then vmax := vmax + c[i,a[i]];
assign(g,gn); rewrite(g);
writeln(g,vmax);
for i := 1 to n do
if (a[i] > 0) then writeln(g,i,bl,a[i]);
close(g);
end;
procedure PrintArray(var a: mi1; d,c: integer);
{ Hien thi mang a[d..c] }
var i: integer;
begin for i := d to c do write(a[i],bl); end;
procedure Update(i,j: integer);
var c: integer;
begin
repeat
c := a[i]; { i bo qua c }
a[i] := j; b[j] := i; { i nhan qua moi j }
i := t[i]; j := c; { chuyen qua nguoi khac }
until c = 0;
end;
procedure Mark(i,j: integer);
{ ghi nhan phuong an i nhan qua j }
var sum: integer;
begin
sum := d[i] + c[i,j]; { neu i nhan qua moi j }
if (sum > dmax) then { ghi nhan phuong an tot hon }
begin
dmax := sum;
imax := i; jmax := j;
end
end;
procedure Nap(i,j: integer);
{ Nap em j vao danh sach nhuong qua cho em i }
begin
if (t[j] > 0) then exit; { j da co trong st }
inc(p); st[p] := j; t[j] := i; { j se nhuong qua cho i }
{ dieu chinh gia tri tich luy }
d[j] := d[i] + c[i,a[j]] - c[j,a[j]] ;
end;
function Xep(i: integer): integer; { tim qua cho em i }
var j: integer;
begin
fillchar(t,sizeof(t),0); d := t;
{ d[j] - do gia tang tich luy den em j }
dmax := 0; p := 0; Nap(i,i);
while (p > 0) do
begin
i := st[p]; dec(p); { lay ngon stack }
for j := 1 to m do { duyet cac mon qua }
if (b[j] = 0) then Mark(i,j) { qua j chua chia }

else Nap(i,j); { danh sach nhuong qua }


end;
Xep := 0;
if (dmax = 0) then exit;
Update(imax, jmax);
Xep := 1; { Xep duoc qua cho em i }
end;
function Par: integer; { Ghep cap }
var i, v: integer;
begin
v := 0;
fillchar(a,sizeof(a),0); b := a;
for i := 1 to n do v := v + Xep(i);
Par := v;
end;
procedure Print; { Hien thi ma tran c }
var i,j: integer;
begin
writeln(nl,' Input: ');
for i := 1 to n do
begin
writeln;
for j := 1 to m do write(c[i,j],bl);
end;
end;
procedure Doc;
var f: text;
i,j,k,r: integer;
begin
fillchar(c,sizeof(c),0);
assign(f,fn); reset(f);
readln(f,n,m);
for i := 1 to n do
for j := 1 to m do
read(f,c[i,j]);
close(f);
end;
procedure Run;
var v: integer;
begin
Doc; Print;
v := Par;
Ghi(v);
writeln(nl, ' ket qua: '); PrintArray(a,1,n);
end;
BEGIN
Run;
writeln(nl,' Fini');
readln;
END.
// Dev-C++: Autum2
#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 = "autum2.inp";
const char * gn = "autum2.out";
const int mn = 201; // so nguoi va so qua toi da
int a[mn]; // a[i] = j: em i nhan qua j
int b[mn]; // b[j] = i: qua j trong tay em i
int t[mn]; // t[j] = i : em j nhuong qua cho ban i
int c[mn][mn]; // c[i][j] = 1: i thich qua j

int d[mn]; // d[j] khi j nhuong qua cho i


int n; // so em nho
int m; // so qua
int st[mn]; // stack
int p; // con tro stack
int imax, jmax, dmax;
// P R O T O T Y P E S
int main();
void Doc();
void Print();
int Par();
int Xep(int);
void Update(int, int);
void PrintArray(int [], int , int );
void Ghi(int);
void Nap(int, int);
void Mark(int, int);
// I M P L E M E N T A T I O N
int main() {
Doc();
Print();
int v = Par();
Ghi(v);
cout << endl << "
Ket qua: "; PrintArray(a,1,n);
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void Ghi(int v) {
int vmax = 0;
for (int i = 1; i <= n; ++i)
if (a[i] > 0) vmax += c[i][a[i]];
ofstream g(gn);
g << vmax << endl;
for (int i = 1; i <= n; ++i)
if (a[i] > 0) g << i << " " << a[i] << endl;
g.close();
}
void PrintArray(int a[], int d, int c) {
int i;
for (i = d; i <= c; ++i) cout << a[i] << " ";
}
void Update(int i, int j){
int c;
do {
c = a[i]; // i bo qua c
a[i] = j; b[j] = i; // i nhan qua moi j
i = t[i]; j = c; // chuyen qua nguoi khac
} while (c > 0);
}
void Mark(int i, int j) {
int sum = d[i]+c[i][j];// neu i nhan qua moi j
if (sum > dmax) { // ghi nhan phuong an tot hon
dmax = sum;
imax = i; jmax = j;
}
}
void Nap(int i, int j) { // Nap j vao st
// em j se nhuong qua a[j] cho em i
// em i bo qua a[i] de lay a[j]
if (t[j]>0) return; // j da co
st[++p] = j; t[j] = i;
d[j] = d[i] + c[i][a[j]] - c[j][a[j]] ;// do lech

}
int Xep(int i) { // tim qua cho em i
memset(t, 0, sizeof(t));
memset(d, 0, sizeof(d)); // d[i] - do lech neu i nhuong qua
int j;
dmax = 0; p = 0; Nap(i,i);
while(p > 0) {
i = st[p--]; // lay ngon stack
for (j = 1; j <= m; ++j) // duyet cac mon qua
if (b[j] == 0) Mark(i,j); // qua j chua chia
else Nap(i,j);// danh sach nhuong qua
} // while
if (dmax = 0) return 0;
Update(imax, jmax);
return 1; // Xep duoc qua cho em i
}
int Par(){ // Cap ghep
int v = 0, i;
memset(a,0,sizeof(a)); memset(b,0,sizeof(b));
for (i = 1; i <= n; ++i) v += Xep(i);
return v;
}
void Print() { // Hien thi ma tran c
cout << endl << " input: ";
cout << endl << n << " " << m << endl;
int i,j;
for (i = 1; i <= n; ++i){
for (j = 1; j <= m; ++j)
cout << c[i][j] << " ";
cout << endl;
}
}
void Doc(){
memset(c,0,sizeof(c));
ifstream f(fn);
f >> n >> m;
int i,j;
for (i = 1; i <= n; ++i)
for (j = 1; j <= m; ++j)
f >> c[i][j];
f.close();
}

Chng 4 Cc php lt v chuyn v

4.1 Lt xu
Cho xu k t s. Hy lt xu s, tc l sp cc k t ca xu s theo trt t ngc li. Th d, vi s = "abcd",
th sau khi o ta thu c s = "dcba".
Thut ton
lt mt on s[d..c] trong dy s bt k ta thc hin lin tip cc php i ch hai phn t cch u u
v cui tnh dn t ngoi vo gia dy.
phc tp
Nu on cn lt c chiu di n, mi ln i ch hai phn t ta cn 3 php gn. Tng cng c n/2 cp phn
t do s php gn s l 3n/2.
Chng trnh
Hm Rev trong cc chng trnh sau y nhn vo mt xu s v hai ch s u d v cui c, sau thc
hin php o on s[d..c] ri cho ra chnh xu s .
(* Reverse.pas *)
uses crt;
const nl = #13#10;
var s: string;
function Rev(var s: string; d,c: integer): string;
var ch: char;
begin
while (d < c) do
begin
ch := s[d]; s[d] := s[c]; s[c] := ch;
inc(d); dec(c);
end;
Rev := s;
end;
BEGIN
s := 'I have a dream';
write(nl,'Given: ',s);
Rev(s,1,length(s));
writeln(' => ',s);
writeln(nl,' Now, the source string is: ', Rev(s,1,length(s)));
readln;
END.
// DevC++: Reverse.cpp
#include <fstream>
#include <iostream>
using namespace std;
// P R O T O T Y P E S
int main();
char * Rev(char *s, int d, int c);
// I M P L E M E N T A T I O N
int main() {
char * s = strdup("I have a dream");

cout << endl << " Given: " << s;


cout << " => " << Rev(s,0,strlen(s)-1);
cout << endl << " Now, the source string is
<< Rev(s,0,strlen(s)-1);
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
char * Rev(char
char ch;
while (d <
ch =
++d;
}
return s;
}

=> "

* s, int d, int c) {
c) {
s[d]; s[d] = s[c]; s[c] = ch;
--c;

Gii thch
Hm s = strdup("I have a dream") cp pht min nh cho xu s v khi tr xu ny bng dy
k t "I have a dream".

4.2 Lt s nguyn
Vit hm Rev(x) cho ra s nguyn dng lt ca s nguyn x. Th d, Rev(1234) = 4321.
Thut ton
Gi y l kt qu. Ta khi tr y = 0 sau ly ln lt cc ch s u phi ca x ghp vo bn phi s y.
phc tp
Nu s cho c n ch s, mi ln chuyn mt ch s ta cn thc hin mt php chia d v hai php nhn.
Nu ta coi thi gian thc hin php nhn, chia v chia d l xp x bng nhau th thut ton lt s nguyn
cn thi gian 3n. Mi s nguyn x c lg(x) + 1 ch s dng thp phn. Vy phc tp c lg(x).
(* RevInt.pas *)
uses crt;
var x,y: integer;
function Rev(x: longint): longint;
var y: longint;
begin
y := 0;
while x <> 0 do
begin
y := y*10 + (x mod 10);
x := x div 10;
end;
Rev := y;
end;
BEGIN
x := -1234;
y := Rev(x);
writeln(' Given: ',x,' => ' ,y);
writeln(' Now, the source number is ', Rev(y));
readln;
END.
// DevC++: RevInt.cpp
#include <fstream>
#include <iostream>
using namespace std;
// P R O T O T Y P E S
int main();
int Rev(int x);
// I M P L E M E N T A T I O N
int main() {

int y, x = -1234;
cout << endl << " Given: " << x;
cout << " => " << (y = Rev(x));
cout << endl << " Now, the source number is
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;

=> " << Rev(y);

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

4.3 Sn bay v tr
Mun a cc con tu v tr vo ng qu o trn khng gian ngi ta cn chn a im thich hp
xy dng ng bng. Nu ng bng t ti v tr thun li, ph hp vi hng vn hnh ca cc hnh
tinh th s tit kim c nhiu nhin liu. Ngi ta xy dng xong mt ng bng ti sn bay v tr.
ng bng gm n tm b tng ln c t ti mt v tr c nh. Trong cc tm b tng cha nhiu linh
kin v ng ni tinh vi do s lin kt rt phc tp. Tuy nhin, lc kim tra ngi ta pht hin ra
s nhm ln ln: i tm b tng u ng bng t sai v tr: chng cn c chuyn v phia cui ng
bng. Rt may l trn cng trng lc ny cn mt xe c chng c sc ch 1 tm b tng v mt cn trc
c sc nng 1 tm b tng. Xe chy trn ng ray song song vi ng bng. Mi tm b tng cn
chuyn c tho cc khp ni v c cn trc cu ln t trn xe ri c xe chuyn n v tr cn t
li. Ti v tr cn trc li cu tm b tng khi xe v t vo v tr thch hp. Cn trc cng c th cu
trc tip 1 tm b tng t mt v tr n v tr cn trng no . Thi gian cu v vn chuyn mt tm b
tng l ng k. Hy xut mt phng n khc phc s c vi thi gian ngn nht, c th l cn gim
ti a s ln cu b tng.
Th d
1

Thut ton

ng bng gm 7 tm b tng m s ln lt t 1 n 7. 3
tm b tng u tin l 1, 2 v 3 b t sai v tr. Sau khi
chuyn li 3 tm ny ta thu c ng bng t ng l
(4, 5, 6, 7, 1, 2, 3).

Phng n 1. Ta gi mi ln cu mt tm b tng l mt thao tc. chuyn i tm b tng t u ng


bng v cui ng bng ta chuyn dn tng tm. chuyn mt tm t t u v cui ng bng ta thc
hin n+1 thao tc sau y:
1 thao tc: Chuyn tm t ra xe x;
n1 thao tc: dch dn n1 tm trn ng bng ln 1 v tr;
1 thao tc: Chuen tm t t xe vo v tr cui ng bng.
Tng hp li, chuyn i tm t u v cui ng bng ta cn T1 = i(n+1) thao tc.
Gi s ng bng c 1000 tm b tng v ta cn chuyn 500 tm b tng t u v cui ng bng th ta
cn T = 500(1000+1) = 500.1001 = 500500 thao tc. Li gi s mi ngy ta c th thc hin c 100
thao tc th thi gian cn thit khc phc s c s l:
500500/(100365(ngy)) 13 nm
Phng n 2. Ta vn dng php i xng (php lt) gii bi ton ny. K hiu u' l dy lt ca dy u.
Th d, u = 1234 th u' = (1234)' = 4321.
Php lt c cc tnh cht sau:
1. Tnh kh nghch hay ly ng: u'' = u. Lt i lt ri lt li mt dy s cho ta dy ban u;
2. Cng tnh ngc: (uv)' = v'u'. Lt mt dy gm hai khc u v v s cho kt qa l mt dy gm hai
khc lt ring r: khc lt th hai v' kt ni vi khc lt th nht u'.
Gi u l khc u gm i tm b tng u ng bng, v l khc cui gm ni tm b tng cn li. Bi ton
t ra l bin i uv thnh vu: uv vu. Vn dng hai tnh cht ca php lt ta c:
(u'v')' = v''u'' = vu
(*)
Ta xt li th d ng bng gm 7 tm b tng v cn chuyn i = 3 tm b tng t u v cui ng
bng. Ta c u = 123; v = 4567.
Nhim v: uv = 1234567 vu = 4567123.
Vn dng ng thc (*) ta c
(u'v')' = ((123)'(4567)')' = (3217654)' = 4567123 = vu
Nu Rev(s,d,c) l th tc lt on t ch s d n ch s c trong dy s(1..n) th biu thc (*) ni trn
c ci t qua ba php gi th tc Rev nh sau:
Rev(s, 1, i); { u' }
Rev(s, i+1, n); { v' }
Rev(s, 1, n); { s' = (u'v')' = vu }
Ta bit, lt mt khc gm m phn t ta cn i ch ln lt mi cp phn t cch u u v cui.
Tng cng c m/2 cp. Mi ln i ch hai phn t trong mt cp ta cn thc hin 3 php gn tng ng
vi 3 thao tc cu. Vy thut tan chuyn v theo cng thc (*) s i hi:
3i/2 thao tc cho u';
3(ni)/2 thao tc cho v';
3n/2 thao tc cho s';
Tng cng ta cn T2 = 3/2. (i+(ni)+n) = 3n thao tc.
Vi th d cho, n = 1000, i = 500 ta tnh c T2 = 3.1000 = 3000, tc l 3000/100 = 30 ngy.
Phng n 1 i hi 13 nm trong khi phng n 2 ch cn 1 thng!
Ch Nu m l s l th khi lt on gm m phn t s ch cn 3(m1)/2 php gn, do cng thc tnh
T2 c th cn nh hn 3n ti a l 6 php gn.
Phng n 3. C th vn dng php ly tch cc hon v gii bi ton vi n+d php chuyn, trong d
l c chung ln nht ca n v i. Gi s ng bng a gm n = 15 tm b tng, a = (1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15) v ta cn chuyn i = 6 tm t u v cui ng bng theo yu cu ca u bi. Kt
qu cui cng phi thu c l b = (7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 6). Nh vy ta c php hon
v a b nh sau:
a
b

1
7

2
8

3
9

4
10

5
11

6
12

7
13

8
14

9
15

10
1

11
2

12
3

13
4

14
5

15
6

Ba hon v vng quanh


xe 1 7 13 4 10 1 (xe);
xe 2 8 14 5 11 2 (xe);
xe 3 9 15 6 12 3 (xe).

Ta s c gng mi ln chuyn 1 tm vo ng v tr cn thit. So snh hai dng a v b ca bng ta c th


thc hin nh sau:
Pha th nht
1. Cu tm 1 ra xe; v tr 1 tr thnh trng,

2. Cu tm 7 vo v tr 1; v tr 7 tr thnh trng,
3. Cu tm 13 vo v tr 7; v tr 13 tr thnh trng,
4. Cu tm 4 vo v tr 13; v tr 4 tr thnh trng,
5. Cu tm 10 vo v tr 4; v tr 10 tr thnh trng,
6. Cu tm 1 t xe vo v tr 10.
Sau 6 thao tc chuyn ta thu c:
1
7

4
10

7
13

10
1

11

12

13
4

14

15

Ta tip tc:
Pha th hai:
7. Cu tm 2 ra xe; v tr 2 tr thnh trng,
8. Cu tm 8 vo v tr 2; v tr 8 tr thnh trng,
9. Cu tm 14 vo v tr 8; v tr 14 tr thnh trng,
10. Cu tm 5 vo v tr 14; v tr 5 tr thnh trng,
11. Cu tm 11 vo v tr 5; v tr 11 tr thnh trng,
12. Cu tm 2 t xe vo v tr 11.
n y ta thu c:
1
7

2
8

4
10

5
11

7
13

8
14

10
1

11
2

12

13
4

14
5

15

Ta li chuyn tip:
Pha th ba:
13. Cu tm 3 ra xe; v tr 3 tr thnh trng,
14. Cu tm 9 vo v tr 3; v tr 9 tr thnh trng,
15. Cu tm 15 vo v tr 9; v tr 15 tr thnh trng,
16. Cu tm 6 vo v tr 15; v tr 6 tr thnh trng,
17. Cu tm 12 vo v tr 6; v tr 12 tr thnh trng,
18. Cu tm 3 t xe vo v tr 12.
1
7

2
8

3
9

4
10

5
11

6
12

7
13

8
14

9
15

10
1

11
2

12
3

13
4

14
5

15
6

Sau T3 = 18 ln cu ta thu c kt qu. Phng n 2 i hi T 2 = 3n = 3.15 = 45 ln cu.


Tng qut, ta hy tng tng cc tm b tng c xp thnh vng trn nh trn mt s ng h, nu xut
pht t v tr s0 sau t nht l k ln chuyn (khng tnh ln chuyn s0 ra xe) ta s thu c dy
xe s0 s1 s2 ... sk = s0 (xe)
Trong tm b tng u tin s0 c chuyn ra xe v cui cng, ti bc th k tm li c chuyn
vo v tr s0. Ta d dng nhn thy sj+1 = (sj + i) mod n, j = 0, 1, ..., k1. T y ta suy ra (s0 + ki) mod n =
s0, hay ki mod n = 0. Gi d l c chung ln nht ca n v i, d = (n,i). Ta c ngay, n = dn' v i = di'. t k =
n' = n/d, ta c kd = n'd = n v ki mod n = n'i mod n = (n/d)i mod n = (ni/d) mod n = ni' mod n = 0. S pha
chuyn l d.
Nh vy tng cng s c tt c T3 = (k+1)d = kd + d = n + d ln chuyn, trong d = (n,i). Vi n = 15, i =
6 ta tnh c d = (15,6) = 3, do ta chuyn trong d = 3 pha v tng s ln chuyn s l T3 = 15 + 3 = 18.
Hm Move di y nhn vo hai gi tr: tng s tm b tng n v s b tng u tin cn chuyn v cui i
sau gii trnh trt t chuyn cc tm b tng theo tng pha.
(* SanBay.pas *)
uses crt;
const BL = #32; NL = #13#10;
function Ucln(a, b: integer): integer;
var r: integer;
begin
while (b <> 0) do
begin
r := a mod b; a := b; b := r;
end;
Ucln := a;
end;
function Move(n, i: integer): integer;
var

d: integer;
tamdau, tam, vitri: integer;
t: integer; { tong so lan chuyen }
j, p: integer;
a: array[0..1000] of integer;
begin
d := Ucln(n,i);
writeln(NL,' Se chuyen trong ', d, ' pha', NL);
t := 0; tamdau := 1;
for j := 0 to n do a[j] := j;
for p := 1 to d do
begin
writeln(NL, ' Pha thu ', p, ':', NL);
while(a[tamdau] <> tamdau) do inc(tamdau);
tam := tamdau; inc(t); a[tam] := 0;
write(NL, t, '. Chuyen tam ', tam , ' ra xe');
readln;
while (true) do
begin
vitri := tam; tam := tam + i;
if (tam > n) then tam := tam n;
inc(t); a[vitri] := tam;
if (tam <> tamdau) then
begin
write(NL,t,'. Chuyen tam ',tam, ' den vi tri ',vitri);
a[tam] := 0;
end
else
begin
write(NL,t,'. Chuyen tam ',tamdau,
' tu xe vao vi tri ', vitri);
write(NL,' Xong pha ',p,NL);
break;
end;
readln;
end { while }
end ; { end for }
write(NL,' Ket qua: ');
for i := 1 to n do write(a[i],BL);
Move := t;
end;
var t: integer;
BEGIN
t := Move(15,6);
writeln(NL, NL, ' Tong cong ', t, ' phep chuyen');
writeln(NL,NL,' Fini');
readln
END.
// DevC++: SanBay.cpp
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
// P R O T O T Y P E S
int Ucln(int a, int b);
int Move(int n, int i);
// I M P L E M E N T A T I O N
main() {
cout << endl << endl
<< " Tong cong " << Move(15,6) << " phep chuyen";
cout << endl << " Fini "; cin.get();

}
int Ucln(int a, int b) {
int r;
while (b) {
r = a % b; a = b; b = r;
}
return a;
}
int Move(int n, int i) {
int d = Ucln(n,i);
cout << endl << " Se chuyen trong " << d << " pha" << endl;
int tam, vitri;
int t = 0; // tong so lan chuyen
int tamdau = 1; // tam be tong can chuyen dau tien cua moi pha
int a[n+1];
int j, p;
for (j = 0; j <= n; ++j) a[j] = j;
for (p = 1; p <= d; ++p) {
cout << endl << " Pha thu " << p << ":" << endl;
while(a[tamdau] != tamdau) ++tamdau;
tam = tamdau;
++t; a[tam] = 0;
cout << endl << t << ". Chuyen tam " << tam << " ra xe";
if (cin.get()=='.') return t;
while (1) {
vitri = tam; tam += i;
if (tam > n) tam -= n;
++t; a[vitri] = tam; // a[tam] = 0;
if (tam != tamdau) {
a[tam] = 0;
cout << endl << t << ". Chuyen tam "
<< tam << " den vi tri " << vitri;
}
else {
cout << endl << t << ". Chuyen tam "
<< tamdau << " tu xe vao vi tri " << vitri;
cout << ". Xong pha " << p << endl;
break;
}
if (cin.get()=='.') return t;
} // end while
} // end for
cout << endl << endl << " Ket qua: ";
for (i = 1; i <= n; ++i) cout << a[i] << " ";
return t;
}

4.4 Cn
Olimpic cc nc vng Baltic, 2004
Ngi ta cn cn mt vt c khi lng l mt s t nhin n gam bng mt b qu cn khi lng 1, 3, 9,
..., 3k, ... gam, k = 0, 1, 2, ... , mi loi c ng mt qu cn. Vt cn cn c t trn a tri. Hy chn
cc qu cn t trn hai a cn thng bng.
can.inp
69

Thut ton

can.out
2 3 9
1 81

Gii thch
Input text file: s n; 1 n 1000000000 (1 t).
Output text file: 2 dng
Dng 1: s qu cn t trn a tri, tip n l cc qu cn c th.
Dng 2: s qu cn t trn a phi, tip n l cc qu cn c th.
Th d, vi khi lng vt cn n = 69 g t trn a tri, ta cn t thm 2
qu cn trn a tri l 3 v 9g; 1 qu cn trn a phi l 81 g. Ta c:
69 + 3 + 9 = 81.

u tin ta tm gi thit l s lng qu cn mi loi l nhiu c th cn mi khi lng trong gii


hn cho trc. Khi ta biu din n di dng h m 3 ri t vt cn cn trn a tri v t cc qu cn
tng ng trn a phi.
biu din n di dng h b ty ta chia lin tip n cho b v ghi nhn cc s d. Trong cc phin bn
di y p l mng nguyn cha cc ch s trong dng biu din ngc ca s n di dng h m b, u
ra ca cc hm ToBase l s ch s trong dng biu din .
type mi1 = array[0..30] of integer;
(* Pascal *)
function ToBase(n: longint; b: integer; var p: mi1): longint;
var i: longint;
begin
fillchar(p, sizeof(p),0);
i := 0;
repeat
p[i] := n mod b;
n := n div b;
inc(i);
until n = 0;
ToBase := i;
end;
// DevC++
int ToBase(int n, int b, int *p) {
int i = 0;
memset(p, 0, sizeof(p));
do {
p[i++] = n % b;
n /= b;
} while (n != 0);
return i;
}

Xut x
Claude Gaspar Bachet de Mziriac (15811638) nh ngn ng hc, nh th v hc gi
Php chuyn nghin cu cc tc phm c in.
Bachet cng rt am m cc bi ton . ng
xut bn cun sch "Nhng bi ton vui v
l th v cc con s". ng cng l ngi pht
biu bi ton l th v chic cn a nh sau:
Xc nh ti thiu mt b qu cn c th cn
mi vt c khi lng t 1 n 40g trn mt
chic cn a. Bachet cho bit ch cn dng 4
qu cn l 1, 3, 9 v 27.
Cun S hc ni ting ca Diophantus do
Bachet dch to cm hng cho rt nhiu th
h cc nh ton hc trn Th gii.

Claude Gaspar Bachet de Mziriac


9/10/1581 26/2/1638
nh tri l ba cun S hc ni ting
ca Diophantus vit vo khong nm
250 ti Trung tm vn ha Alexandria
do Bachet dch v xut bn nm 1621.

Ngun: Internet; Simon Sigh, nh l cui


cng ca Fermat (Phm Vn Thiu, Phm Vit
Hng bin dch)

tin lp lun ta tm qui c gi qu cn 3i l qu cn loi i, tc l ta gi theo s m ca h s 3. Vi th


d d cho n = 69, li gi k = ToBase(69, 3, phai) s cho k = 4 v mng phai[0..3] = (0, 2, 1, 2)
chnh l cc ch s h m 3 trong dng biu din ca s 69. C th l s 69 c biu din ngc trong h
m 3 s l mt s gm k = 4 ch s ln lt tnh t ch s hng n l 0, 2, 1 v 2, c th l:
69 = 0.30 + 2.31 + 1.32 + 2.33 = 21203.
Loi qu
cn

0
(30=1)

1
(31=3)

2
(32=9)

3
(33=27)

4
(34=81)

a tri
(69+...)

a phi

Vt cn cn khi lng n = 69 c t trn


a tri. Trn a phi t 3 qu cn:
phai[1] = 2 qu cn loi 1, 2.31 = 6 g,
phai[2] = 1 qu cn loi 2, 1.32 = 9 g,
phai[3] = 2 qu cn loi 3, 2.33 = 2.27 = 54 g,
69 = 6 + 9 + 54.
a tri tm thi trng

V mi loi qu cn ch c ng 1 qu nn ta cn tm cch thay 2 qu cn cng loi i bng t hp khc. Ta


c
2.3i = 3.3i 3i = 3i+1 3i.
H thc trn cho ta thy rng c th thay 2 qu cn loi i a cn phi bng cch t 1 qu cn loi i+1
trn a phi v 1 qu cn loi i trn a tri. Vi th d cho, phai[1] = 2 nn ta thay 2 qu cn loi 1
bng 1 qu cn loi 2 trn a phi v 1 qu cn loi 1 trn a tri. V trn a phi c sn 1 qu cn loi
2 nn s qu cn loi ny s c tng thm 1 v bng 2. Ta thu c:
Loi qu
cn
a tri
(69+...)
a phi

0
(30=1)

1
(31=3)

2
(32=9)

3
(33=27)

4
(34=81)

phai = (0,2,1,2) (0,0,2,2);


trai = (0,1,0,0).
a tri (69 g)+1 qu cn loi 1 = 69 + 3 =
72g;
a phi: 2 qu cn loi 2 + 2 qu cn loi 3
= 2.32+2.33 = 2.9 + 2.27 = 18 + 54 = 72g.

Li thc hin php thay 2 qu cn loi 2 trn a phi bng 1 qu cn loi 2 trn a phi v 1 qu cn loi 3
trn a tri ta thu c:
Loi qu
cn

0
(30=1)

1
(31=3)

2
(32=9)

3
(33=27)

4
(34=81)

phai = (0,0,2,2) (0,0,0,3);

a tri
(69+...)
a phi

trai = (0,1,1,0).
a tri (69g) + 1 qu cn loi 1 + 1 qu cn
loi 2 = 69 + 1.31 + 1.32 = 69 + 3 + 9 = 81 g;
a phi: 3 qu cn loi 3 = 3.27 = 81 g.

Cui cng ta thay 3 qu cn loi 3 trn a phi bng 1 qu cn loi 4 l hon tt.
phai = (0,0,0,3) (0,0,0,0,1).
trai = (0,1,1,0).
Kt qu ta thu c: cn vt n = 69 g ta t vt trn a tri v
t tip trn a tri 2 qu cn 3 v 9 g;
t trn a phi 1 qu cn 81 g.
Tng hp li ta c thut ton Replace thc hin php thay cc qu cn loi i trn a phi nh sau:
Nu trn a phi c 2 qu cn loi i th thay bng 1 qu loi i+1 trn a phi v 1 qu loi i trn
a tri;
Nu trn a phi c 3 qu cn loi i th thay bng 1 qu loi i+1 trn a phi.
Hm Replace nhn vo l dy k qu cn trn a phi p[0..k1], cho ra dy m qu cn trn a tri
t[0..m1]:
(* Pascal *)
function Replace(var p: mi1; var k: integer; var t: mi1): longint;
var m, i: longint;
begin
fillchar(t, sizeof(t),0);
for i := 0 to k do
if p[i] = 3 then begin p[i] := 0; inc(p[i+1]) end
else if p[i] = 2 then
begin p[i] := 0; inc(p[i+1]); inc(t[i]) end;
m := k;
if p[k] > 0 then inc(k);
Replace := m;
end;
// DevC++
int Replace(int * p, int &k, int * t) {
int i, m;
memset(t, 0, sizeof(t));
for (i = 0; i < k; ++i)
if (p[i] == 3) { p[i] = 0; ++p[i+1]; }
else if (p[i] == 2) { p[i] = 0; ++p[i+1]; ++t[i]; }
m = k;
if (p[k] > 0) ++k;
return m;
}
Trc khi ghi file chng ta cn thu dn s b d liu. Ta duyt cc phn t ca hai dy tri v phi m
xem c bao nhiu qu cn v qui cc loi qu cn thnh gi tr c th, tc l thay v vit i ta phi vit 3 i.
(* can.pas *)
uses crt;
const fn = 'can.inp'; gn = 'can.out';
mn = 30; bl = #32; nl = #13#10;
type mi1 = array[0..mn] of longint;
function Doc: longint;
var n: longint;
f: text;
begin
assign(f,fn); reset(f);
readln(f,n); close(f);
Doc := n;
end;
function ToBase(n: longint; b: longint; var p: mi1): longint;
var i: longint;
begin

fillchar(p, sizeof(p),0);
i := 0;
repeat
p[i] := n mod b;
n := n div b;
inc(i);
until n = 0;
ToBase := i;
end;
function Replace(var p: mi1; var k: longint; var t: mi1): longint;
var m, i: longint;
begin
fillchar(t, sizeof(t),0);
for i := 0 to k do
if p[i] = 3 then begin p[i] := 0; inc(p[i+1]) end
else if p[i] = 2 then
begin p[i] := 0; inc(p[i+1]); t[i] := 1 end;
m := k;
if p[k] > 0 then inc(k);
Replace := m;
end;
procedure Ghi(var t: mi1; dt: longint; var p: mi1; dp: longint);
var i, v, nt, np: longint;
g: text;
begin
v := 1; nt := 0;
for i := 0 to dt-1 do
begin
if t[i] > 0 then begin inc(nt); t[i] := v; end;
v := v * 3;
end;
v := 1; np := 0;
for i := 0 to dp-1 do
begin
if p[i] > 0 then begin inc(np); p[i] := v; end;
v := v * 3;
end;
assign(g,gn); rewrite(g);
write(g,nt,bl);
for i := 0 to dt-1 do
if t[i] > 0 then write(g,t[i],bl);
write(g,nl,np,bl);
for i := 0 to dp-1 do
if p[i] > 0 then write(g,p[i],bl);
close(g);
end;
procedure Run;
var trai, phai: mi1;
n, dt, dp: longint;
begin
n := Doc;
dp := ToBase(n,3,phai);
dt := Replace(phai, dp, trai);
Ghi(trai,dt,phai,dp);
end;
BEGIN
Run;
write(nl,' Fini');
readln;
END.
// Devcpp Can.cpp
#include <iostream>

#include <fstream>
using namespace std;
// D A T A
A N D V A R I A B L E
const char * fn = "CAN.INP";
const char * gn = "CAN.OUT";
// P R O T O T Y P E S
int main();
int Doc();
void Ghi(int *t, int n, int *p, int m);
int ToBase(int n, int b, int *p);
int Replace(int *p, int &n, int *t);
void Run();
// I M P L E M E N T A T I O N
int main() {
Run();
cout << endl << endl << " Fini ";
cin.get();
return 0;
}
void Run() {
const int mn = 20;
int phai[mn], trai[mn];
int dp, dt, n;
n = Doc();
dp = ToBase(n, 3, phai);
dt = Replace(phai, dp, trai);
Ghi(trai,dt,phai,dp);
}
int Doc() {
int n;
ifstream f(fn);
f >> n;
f.close();
return n;
}
void Ghi(int *t, int dt, int *p, int dp) {
int i, v, nt, np;//dt,dp: so qua can tren dia trai va phai
nt = np = 0;
for (v = 1,i = 0; i < dt; ++i, v*= 3)
if (t[i] > 0) { ++nt; t[i] = v; }
for (v = 1,i = 0; i < dp; ++i, v*= 3)
if (p[i] > 0) { ++np; p[i] = v; }
ofstream g(gn);
g << nt << " ";
for (i = 0; i < dt; ++i)
if (t[i] > 0) g << t[i] << " ";
g << endl << np << " ";
for (i = 0; i < dp; ++i)
if (p[i] > 0) g << p[i] << " ";
g.close();
}
// Bieu dien so n qua he b
// return i - chieu dai so trong he b
// n = p[0].b^0 + p[1].b^1 + ... + p[i].bi
int ToBase(int n, int b, int *p) {
int i = 0;
memset(p, 0, sizeof(p));
do {
p[i++] = n % b;
n /= b;
} while (n != 0);
return i;
}

int Replace(int * p, int &k, int * t) {


int i, m;
memset(t, 0, sizeof(t));
for (i = 0; i < k; ++i)
if (p[i] == 3) { p[i] = 0; ++p[i+1]; }
else if (p[i] == 2) { p[i] = 0; ++p[i+1]; ++t[i]; }
m = k;
if (p[k] > 0) ++k;
return m;
}
phc tp: c log3(n); trong log3(n) + 1 l s ch s trong dng biu din ca n theo h m 3.

4.5 Biprime
Cp s t nhin x v s lt ca n, x' nu ng thi l hai s nguyn t khc nhau th c gi l cp song
nguyn t. Hy lit k cc cp song nguyn t trong khong 1..N = 500000.
biprime.inp
100

biprime.out
4
13 31
17 71
37 73
79 97

Gii thch
Input text file: s N
Output text file: Dng u tin: M s cp song nguyn t. Tip n
l M dng, mi dng mt cp song nguyn t.
Vi n = 100 ta tm c 4 cp song nguyn t: (13, 31), (17, 71),
(37, 73) v (79, 97).
Cc s cng dng cch nhau qua du cch.

Thut ton
Trc ht dng thut ton sng tm v ghi nhn cc s nguyn t trong khong 1..N. Dng mng a nh
du cc s nguyn t. Nu bit th i bng 0 th i l s nguyn t. Cc th tc x l bit bao gm:
BitOn(i): t bit th i trong a bng 1 (bt bit i);
BitOf(i): t bit th i trong a bng 0 (tt bit i);
GetBit(i): cho gi tr 0/1 ca bit th i trong dy bit a.
Vi Nmax = 500000 th mng a c kch thc (Nmax+7)/8 = 625000 byte. Bit th i trong dy a
s ng vi bit th i%8 trong byte b = i/8. Ch rng i%8 = i&7 v i/8 = (i>>3).
Sau khi gi th tc Sang ta duyt li dy bit a, vi mi s nguyn t i (GetBit(i)=0) ta tm s lt ip
= Rev(i). Nu ip i, ip N v ip cng l s nguyn t th ta m s cp. Ta s dng bng
quyt nh xc nh khi no th cn nh du (t BitOn(i) hoc BitOn(ip)). Nu i v s lt ip ca
n l cp song nguyn t th ta ch cn nh du mt trong hai s bng th tc BitOn. Ln duyt th
hai ta ch quan tm nhng bit i nhn gi tr 0 v ghi li cc cp i v Rev(i).

iu
kin

Quyt
nh

Bng quyt nh xa i v s lt
i nguyn t
yes
yes
yes
yes
ip N
ip i
yes
yes
ip nguyn t
yes
no
no
yes
Xa i (BitOn(i))
yes
no
Xa ip (BitOn(ip))

yes
yes
no

yes
no

yes
no

yes
no

ip = Rev(i).
Xa x tc l t BitOn(x).

phc tp
Th tc sng i hi

n php chia d v n ln duyt cho mi s nguyn t do bi ton i hi


phc tp tnh ton c n n .
(* Biprime.pas *)
uses crt;
const mn = (500000+7) shr 3;
fn = 'biprime.inp'; gn = 'biprime.out';
bl = #32; nl = #13#10;

type mb1 = array[0..mn] of byte;


var a: mb1;
procedure BitOn(i: longint); { bt bit i }
var p, b: longint;
begin
b := i shr 3; p := i and 7;
a[b] := a[b] or (1 shl p);
end;
procedure BitOff(i: longint); { tt bit i }
var p, b: longint;
begin
b := i shr 3; p := i and 7;
a[b] := a[b] and (not(1 shl p));
end;
function GetBit(i: longint): integer; { nhn gi tr ca bit i }
var p,b: longint;
begin
b := i shr 3; p := i and 7;
GetBit := (a[b] shr p) and 1;
end;
procedure Sang(n: longint);
var i,j: longint;
begin
fillchar(a,sizeof(a),0);
for i := 2 to round(sqrt(n)) do
if GetBit(i) = 0 then
for j := i to (n div i) do BitOn(i*j);
end;
function Rev(x: longint): longint; { s lt ca x }
var y: longint;
begin
y := 0;
while x <> 0 do
begin
y := y*10 + (x mod 10);
x := x div 10;
end;
Rev := y;
end;
function Doc: longint;
var n: longint;
f: text;
begin
assign(f,fn); reset(f);
readln(f,n); close(f);
Doc := n;
end;
procedure Run;
var n, i, ip, d: longint;
g: text;
begin
n := Doc;
Sang(n);
d := 0;
for i := 13 to n do
if GetBit(i) = 0 then { i nguyn t }
begin
ip := Rev(i);
if (ip <= n) and (ip <> i) then
begin
if GetBit(ip) = 0 then { ip nguyn t }
begin
inc(d);

BitOn(ip); { xa ip }
end else BitOn(i); { xa i }
end else BitOn(i);
end;
{ Ghi file }
assign(g,gn); rewrite(g);
writeln(g,d);
for i := 13 to n do
if GetBit(i) = 0 then
writeln(g,i,bl,Rev(i));
close(g);
end;
BEGIN
Run;
write(nl,' Fini'); readln;
END.
// Devcpp biprime.cpp
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
// D A T A
A N D V A R I A B L E
const char * fn = "biprime.inp";
const char * gn = "biprime.out";
const int mn = (500000+7)>>3;
char a[mn];
// P R O T O T Y P E S
int main();
int Doc();
void BitOn(int i);
void BitOff(int i);
int GetBit(int i);
int Rev(int x);
void Sang(int n);
void Run();
// I M P L E M E N T A T I O N
int main() {
Run();
cout << endl << endl << " Fini ";
cin.get();
return 0;
}
int Doc() {
int n;
ifstream f(fn);
f >> n;
f.close();
return n;
}
void BitOn(int i) { // bt bit i
int b = i >> 3, p = i & 7;
a[b] |= (1 << p);
}
void BitOff(int i) { // tt bit i
int b = i >> 3, p = i & 7;
a[b] &= ~(1 << p);
}
int GetBit(int i) { // nhn tr ca bit i
int b = i >> 3, p = i & 7;
return (a[b] >> p) & 1;
}
int Rev(int x) { // s lt ca x
int y = 0;

do {
y = y*10 + (x % 10);
x /= 10;
} while (x);
return y;
}
void Sang(int n) {
int can = int(sqrt(n));
int i, j, ni;
for (i = 2; i <= can; ++i)
if (GetBit(i) == 0)
for (ni = n/i, j = i; j <= ni; ++j) BitOn(i*j);
for (i = 13; i <= n; ++i)
if (GetBit(i) == 0) cout << i << " ";
}
void Run() {
int i , n, d, ip;
n = Doc();
memset(a, 0, sizeof(a));
cout << endl << " n = " << n << " mn = " << mn << endl;
Sang(n);
for (d = 0, i = 13; i <= n; ++i)
if (GetBit(i) == 0) {
ip = Rev(i);
if ((ip <= n) && (ip != i)) {
if (GetBit(ip) == 0) {
++d; BitOn(ip); // xa ip
} else BitOn(i); // xa i
} else BitOn(i); // xa i
}
// Ghi file
ofstream g(gn);
g << d << endl;
for (i = 13; i <= n; ++i)
if (GetBit(i) == 0)
g << i << ' ' << Rev(i) << endl;
g.close();
}

4.6 Chuyn bi
Trn mt bng chia 2n+1 ngi ta t n vin bi xanh lin nhau, mi 1 vin, sau b mt trng v
t tip n vin bi nh hnh a. Hy tm cch chuyn vi s ln t nht thu c hnh b, trong cc
vin bi xanh c chuyn qua tri ca trng, cc vin bi c chuyn qua phi trng. Mi ln c
php chuyn mt vin bi vo trng k vin bi hoc cch vin bi 1 .
(a)

(b)

balls.inp
3

balls.out
bbborrr
bbobrrr
bbrborr

Gii thch
Input text file: s N.

bbrbror
bbrorbr
borbrbr
obrbrbr
rbobrbr
rbrbobr
rbrbrbo
rbrbrob
rbrorbb
rorbrbb
rrobrbb
rrrbobb
rrrobbb
15

Output text file: Dng u tin - cu hnh xut pht l mt xu


gm N k t 'b' biu th bi xanh (blue), tip n l 1 k t 'o' biu
th trng, tip n l N k t 'r' biu th bi (red).
Tip n l M dng, mi dng l mt cu hnh thu c sau mi
ln chuyn.
Dng cui cng: M - tng s ln chuyn.

Thut ton
Ta k hiu x(n) l dy gm n ch ci x. Bi ton khi c pht biu nh sau:
b(n)or(n) r(n)ob(n)
Nu chuyn dn tng vin bi xanh n v tr cn thit bn phi th mi ln chuyn mt bi xanh qua phi
mt v tr ta phi theo s vi 2 bc chuyn nh sau:
...bor... ...obr... ...rbo...
thc hin php chuyn mt bi xanh v cui dy b(n)or(n) = b(n-1)bor(n) b(n-1)r(n)bo ta cn 2n bc
chuyn. Sau ta li phi thc hin n+1 bc chuyn trng v u tri ca dy r(n) theo s :
b(n-1)r(n)bo b(n-1)or(n)b
Vy chuyn mt bi xanh v cui dy sau a trng v u tri ca dy r(n) theo s
...bor(n) ...r(n)bo ...or(n)b
ta cn 3n+1 bc chuyn.
chuyn n-1 bi xanh qua phi theo s
b(n)or(n) = bb(n-1)or(n) bor(n)b(n-1)
ta cn (n-1)(3n+1) bc chuyn.
Vi vin bi xanh cn li cui cng ta s chuyn theo s sau
bor(n)b(n-1) r(n)bob(n-1) (2n bc chuyn) r(n)obb(n-1) (1 bc chuyn) = r(n)ob(n).
Vy tng cng ta cn (n-1)(3n+1)+2n+1 = 3n2+n-3n-1+2n+1 = 3n2 bc chuyn.
Vi n = 3 ta cn 3.32 = 27 bc chuyn c th nh sau:
bbborrr bbobrrr bbrborr bbrobrr bbrrbor bbrrobr bbrrrbo bbrrrob
bbrrorb bbrorrb bborrrb bobrrrb brborrb brobrrb brrborb brrobrb
brrrbob brrrobb brrorbb brorrbb borrrbb obrrrbb rborrbb robrrbb
rrborbb rrobrbb rrrbobb rrrobbb.
Ta s ci tin thut ton trn thu c mt thut ton vi s bc chuyn l n(n+2). Ta gi thut ton
ny l thut ton qu lc v c ch hot ng ca n rt ging vi dao ng ca qu lc. Trc ht ta
xut mt s heuristics tr gip cho vic ti u ha s ln chuyn:
Khng bao gi chuyn bi i li, ngha l bi xanh phi lun lun c chuyn qua phi, bi qua
tri,
Phi chuyn bi i nhanh nht c th, ngha l phi tm cch chuyn bi qua 2 thay v qua mt
mi bc.
Ta theo di s di chuyn ca trng. Ta k hiu 1 nu trng c chuyn qua tri 1 v tr, +1 nu
trng c chuyn qua phi 1 v tr; +2(k) nu trng c chuyn qua phi k ln, mi ln 2 v tr v
2(k) nu trng c chuyn qua tri k ln, mi ln 2 v tr. Vi n = 3 nh th d cho, ta c dy gm
15 php chuyn trng nh sau:
Cu hnh ban u: bbborrr
1; +2(1): bbobrrr, bbrborr - dch trng qua tri 1 sau dch trng qua phi 1 ln nhy 2 ,
+1; 2(2): bbrbror, bbrorbr, borbrbr - dch trng qua phi 1 sau dch trng qua tri 2 ln, mi ln 2
,
1; +2(3): obrbrbr, rbobrbr, rbrbobr, rbrbrbo - dch trng qua tri 1 sau dch trng qua phi 3 ln,
mi ln 2 ,
1; 2(2): rbrbrob, rbrorbb, rorbrbb - dch trng qua tri 1 sau dch tip trng qua tri 2 ln, mi
ln 2 ,
+1; +2(1): rrobrbb, rrrbobb, - dch trng qua phi 1 sau dch tip trng qua phi 1 ln nhy 2 ,
1: rrrobbb - dch trng qua tri 1 . Hon thnh.
Bn d dng pht hin rng thut ton trn vn dng ti a 2 heuristics ni trn.

Tng qut, ta m t thut ton theo s sau:


Pha 1: (1)i ; (1)i+1.2(i); i = 1, 2, ..., n - hai php chuyn tri du nhau;
Pha 2: (1)i+1 ; (1)i+1.2(i); i = n1, ..., 1 hai php chuyn cng du.
Cui cng thc hin php chuyn 1.
Ta s dng th tc Move(h,k) : chuyn trng k ln, mi ln h , h = 1, 1, 2, 2. Nu h > 0 th chuyn
qua phi, ngc li, khi h < 0 th chuyn qua tri. Khi s hai pha ni trn c trin khai nh sau:
Pha 1: Move((1)i, 1); Move((1)i+1*2, i); i = 1, 2, ..., n.
Pha 2: Move((1)i+1, 1); Move((1)i+1*2, i); i = n1, ..., 1.
Nu ta rng (1)i v (1)i+1 tri du nhau v (1)i+1 v (1)i+1 cng du th hai pha ni
trn c th ci t thng qua mt bin nguyn sign qun l du nh sau:
(* Pascal *)
{ Pha 1 }
sign := -1;
for i := 1 to n do
begin Move(sign, 1); sign := -sign; Move(sign*2,i) end;
{ Pha 2 }
sign := -sign;
for i := n-1 downto 1 do
begin Move(sign, 1); Move(sign*2,i); sign := -sign end;
// Devcpp
// Pha 1
sign = -1;
for (i = 1; i <= n; ++i) {
Move(sign, 1); sign = -sign; Move(sign*2,i);
}
// Pha 2
sign = -sign;
for (i = n-1; i > 0; --i){
Move(sign, 1); Move(sign*2,i); sign = -sign;
}
Chng trnh
(* balls.pas *)
uses crt;
const fn = 'balls.inp'; gn = 'balls.out'; nl = #13#10;
var n, v: integer;
d: longint;
(* n - so vien bi xanh = so vien bi do
v - vi tri o trong
d - tong so lan dich chuyen
*)
a: string;
f,g: text;
procedure Init;
var i: integer;
begin
a := '';
for i := 1 to n do a := a + 'b';
a := a + 'o';
for i := 1 to n do a := a + 'r';
d := -1; v := n+1; { vi tri o trong o }
end;
procedure PP; begin writeln(g,a); inc(d) end; { Ghi file }
procedure Swap(i,j: integer);
var c: char;
begin c := a[i]; a[i] := a[j]; a[j] := c; PP end;
(* chuyen bi
h > 0: qua phai h o
h < 0: qua trai h o
k: so lan

*)
procedure Move(h,k: integer);
var i: integer;
begin
for i := 1 to k do
begin
Swap(v, v+h);
v := v + h;
end;
end;
procedure Balls;
var i, sign: integer;
begin
assign(f,fn); reset(f); readln(f,n); close(f);
assign(g,gn); rewrite(g);
Init;
writeln(n);
PP;
sign := -1;
for i := 1 to n do
begin Move(sign, 1); sign := -sign; Move(sign*2,i) end;
sign := -sign;
for i := n-1 downto 1 do
begin Move(sign, 1); Move(sign*2,i); sign := -sign end;
Move(-1,1);
writeln(g,d); close(g);
end;
BEGIN
Balls;
writeln(nl,' Total ',d, ' move(s)',nl);
write(nl,' Fini');
readln;
END.
// DEV-C++: balls.cpp
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L E
const int mn = 202;
char a[mn];
int n, v, n2, d;
/* n - so vien bi xanh = so vien bi do
v - vi tri o trong
n2 = 2n+1 - tong so o
d - tong so lan dich chuyen
*/
// P R O T O T Y P E S
void Init();
void PP();
void Run();
void Balls();
void Swap(int, int);
void Move(int, int);
ofstream f("BALLS.OUT");
// I M P L E M E N T A T I O N
int main(){
Balls();
f << d; f.close();
cout << endl << " Total " << d << "
cout << endl << " Fini";
system("PAUSE");

move(s)" << endl;

return EXIT_SUCCESS;
}
void Init() {
int i;
for (i = 1; i <= n; ++i) a[i] = 'b'; // blue
a[n+1] = 'o';
n2 = n+n+1;
for (i = n+2; i <= n2; ++i) a[i] = 'r'; // red
d = -1; v = n+1; // vi tri o trong o
}
void PP() { // Ghi file
for (int i = 1; i <= n2; ++i) f << a[i];
f << endl;
++d;
}
void Swap(int i, int j) {
char c = a[i]; a[i] = a[j]; a[j] = c;
PP();
}
/* chuyen bi
h > 0: qua phai h o; h < 0: qua trai h o; k: so lan
*/
void Move(int h, int k) {
for (int i = 0; i < k; v += h, ++i) Swap(v, v+h);
}
void Balls() {
ifstream inf("BALLS.INP");
inf >> n; inf.close();
Init();
cout << n ; PP();
cout << endl;
int i, sign = -1;
for (i = 1; i <= n; ++i) {
Move(sign, 1); sign = -sign; Move(sign*2,i);
}
sign = -sign;
for (i = n-1; i > 0; --i){
Move(sign, 1); Move(sign*2,i); sign = -sign;
}
Move(-1,1);
}
phc tp
Ti pha 1 ta chuyn trng 1 v tr n ln v 2 v tr (1 + 2 +...+n) ln, tng cng n + n(n+1)/2 ln.
Ti pha 2 ta chuyn tng t nh trn nhng vi n1 ln: Ta c tng cng (n1) + n(n1)/2.
Ln cui cng ta chuyn 1 ln trng qua tri.
Vy tng cng s ln chuyn l: t = n + n(n+1)/2 + (n1) + n(n1)/2 + 1 = n(n+2). Vi n = 3 ta cn 3.5 =
15 ln thay v 27 ln nh thut ton th nht.

4.7 Lt nn 2

Ngi ta cn lt kn mt nn nh hnh vung cnh di n = 2t, (t l mt s t nhin trong khong 1..6)


khuyt mt thot nc ti v tr (x,y) bng nhng vin gch mu hnh thc th (ch L) to bi 3 vung
n v nh trong hnh 4.7.1(b). Hai vin gch k cnh nhau, d ch 1 n v di, phi c mu khc nhau.
Hy cho bit mt cch lt vi s mu t nht.

Nn nh kch thc 88
(t = 3). L thot nc ti
dng 5 ct 6

b) Gch lt
b) Gch lt

a) Nn nh

Hnh 4.7.1
D liu vo: tp vn bn SQUARE.INP:
Dng u tin: s t nhin n;
Dng th hai: hai s t nhin x y cch nhau qua du cch, trong x l ta dng, y l ta ct ca l
thot nc.
Nn nh kch thc n c m s dng 1, 2, , n tnh t trn xung v m s ct 1, 2, , n tnh t tri qua phi.
D liu ra: tp vn bn SQUARE.OUT:
Hai dng u tin ghi li cc d liu ca input file;
Dng th ba: s mu cn dng cho vic lt nn.
Tip n l mt phng n lt nn tm c, trong mi vin gch lt c to bi ba ch s ging
nhau th hin mu ca vin gch . Cc s trn mi dng cch nhau qua du cch. thot nc
c ghi s 0.
Th d, vi n = 8 v that nc ti v tr x = 5, y = 6 ta c
mt cch lt nn nh hnh v.

NEN.INP
8
5 6

Thut ton
1

V s mu, vi n = 2 th ch
cn 1 vin gch mu 1. Vi mi n
ln hn 2 ta s trnh by mt thut
ton cn ti a ba mu. Ta s gii
bi ton qua hai pha. Trc ht
ta lt nn nh cha mt
trng ti gc cui cng (n,n)
ca nn nh. Sau ta s tm
cch dch chuyn trng ny
n v tr (x,y) cn thit.

NEN.OUT
8
5
3
1
1
3
3
1
1
3
3

6
1
2
2
3
1
2
2
3

3
2
1
1
3
3
2
1

3
3
1
2
2
3
1
1

1
1
3
2
1
1
3
3

1
2
3
3
0
1
2
3

3
2
2
1
3
2
2
1

3
3
1
1
3
3
1
1

Phn lt nn trnh by chi tit tp 1. Th tc ny c tn l Fill


v hot ng nh sau. u tin ta khi tr vi hnh vung cnh k = 2
nm gc trn tri ca nn nh c biu din di dng mt mng
hai chiu a: ba trong hnh vung 2 2 s c in gi tr 1, nm gc di phi c in gi tr 2
(phn t m). Nh vy, sau khi khi tr ta coi nh lt xong nn nh cnh n = 2 bng 1 vin gch mu 1,
l thot nc nm gc di-phi ( (1,1)). Gi hnh c khi tr l A. Mi bc tip theo ta thc hin
ba thao tc bin hnh sau y:
- Tnh tin A i xung theo ng cho thu c hnh B (xem th tc Copy).
- Lt A sang phi (tc l ly i xng gng qua trc tung) thu c hnh C (xem th tc
Right).
- Lt A xung di (tc l ly i xng gng qua trc honh) thu c hnh D (xem th tc
Down).
Ch rng khi lt ta cn thc hin thm php hon i tr 1 v 3 cho nhau.
Hnh 4.7.2 Nn nh vi n = 8
(t = 3)

Hnh 4.7.3
Mi ln lp nh vy ta s thu c hnh vung c cnh tng gp i hnh trc. Khi k = n ta thu c nn
nh c lt bng cc vin gnh ch L vi ti a 3 mu 1, 2 v 3 cho trng hp n > 2. Ring (n,n) mang
gi tr 2 s c sa thnh 0.
By g ta chuyn qua pha th hai: Dch chuyn trng ti (n,n) n v tr (x,y). Ta s s dng thao tc c
bn sau y: dch chuyn (d,c) ti gc mt hnh vung cnh k ti tm ca hnh vung c th l ti mt
trong 4 nm ti tm ca hnh vung ny.
trng (8,8) c dch
chuyn n tm, ti
(4,4). Hng dch chuyn
dx = 1 (theo dng) v dy
= 1 (theo ct).
A C

D B

Hnh 4.7.4
Th tc ny c tn l ToCenter(k). dch chuyn theo dng v ct ph thuc vo hng dch
chuyn. Ta gi dx l dch chuyn (mi bc 1 ) theo dng v dy l dch chuyn theo ct. Khi cn
dch trng v tm theo hng B A ta t dx = dy = 1; theo hng D C ta t dx = 1, dy = 1; theo
hng C D ta t dx = 1, dy = 1.
Mun a trng (d,c) v v tr (x,y) trc ht ta xc nh xem hai ny ri vo mnh no trong cc mnh
phn t ca hnh vung cnh k. Ta dng 2 bit biu din mnh s hiu dng v ct ln hn hay nh
hn k/2. Nh vy gi tr 01 ng vi mnh : ta dng ca (x,y) ang xt x k/2 v ta ct ca
y > k/2. Vy (x,y) ang xt nm trong mnh phn t 1. Theo cch m ha nh phn ny, mi mnh s
c m s nh sau: A = 0 = 002, B = 3 = 112, C = 1 = 012 v D = 2 = 10. Sau khi a c (c,d) v tm
ta cn phi thc hin mt bc nh na l chuyn tip ny trong phm vi 4 tm (c,d) ri vo
cng mnh vi (x,y). Th tc ny c tn l Equalize.
Vi mi hnh vung cnh k ta chia lm 4 phn A, B, C v D ri gi th tc Equalize a hai
(c,d) v (x,y) v cng mt mnh phn t. Sau mt s ln lp ta thu c k = 2. Khi trong hnh vung 4
cha hai (c,d) v (x,y), trong (c,d) l trng, 3 cn li cng mu, ta ch lm php i ch hai (c,d)
v (x,y) l thu c kt qu.
phc tp
Th tc lt nn duyt mi 1 ln nn i hi n2 php gn.
Gi s n = 2t. Th tc chuyn (c,d) ti gc di phi ca nn nh, tc l t v tr (n,n) v v tr l thot
nc (x,y) i hi t ln lp, mi ln lp ta phi dch chuyn ti a v/2 ln, trong v l chiu di cnh ca
mnh nn nh hnh vung ang xt. Mi ln dch chuyn ta i ch 2 , do cn 3 php gn. Tng cng
th tc ny i hi c 3t(n/2+n/22++n/2t) = 3tn(1/2+1/22++1/2t) =3tn(11/2t+1) /(11/2) = 6tn(1/2t+1).
V n = 2t nn i lng trn c rt gn thnh 6tn(1/2n) = 3t vi t = log2(n).
Tng hp li, phc tp ca bi ton vo c n2.
Chng trnh
(* square.pas *)

uses crt;
const fn = 'square.inp'; gn = 'square.out';
bl = ' '; nl = #13#10; mn = 101;
type mi1 = array[0..mn] of integer;
mi2 = array[0..mn] of mi1;
var
a: mi2;
n: integer; { chieu dai nen nha }
x,y : integer; { Vi tri lo thoat nuoc }
colors: integer; { so mau gach lat }
sx, sy: integer; { goc tren trai cua manh dang xet }
d, c: integer; { dong (d) va cot (c) chua o trong }
qdc, qxy: integer;
{ qdc: manh chua o trong d c; qxy: manh chua o x y }
dx, dy: integer; { huong dich chuyen o trong }
procedure ReadData;
var f: text;
begin
assign(f,fn); reset(f);
readln(f,n,x,y);
close(f);
writeln(nl, n, bl, x, bl, y);
end;
procedure Down(k: integer); { Lat xung }
var i, j, ii, k2: integer;
begin
ii := k; k2 := 2*k;
for i := k+1 to k2 do
begin
for j := 1 to k2 do
a[i][j] := 4-a[ii][j];
dec(ii);
end;
end;
procedure Right(k: integer); { Lt phi }
var i, j, jj, k2: integer;
begin
jj := k; k2 := 2*k;
for j := k+1 to k2 do
begin
for i := 1 to k2 do
a[i][j] := 4-a[i][jj];
dec(jj);
end;
end;
procedure Copy(k: integer); { Tnh tin theo ng cho }
var i, j: integer;
begin
for i := 1 to k do
for j := 1 to k do
a[i+k][j+k] := a[i][j];
end;
procedure Fill; { Lt nn nn }
var k: integer;
begin
a[1][1] := 1; a[1][2] := 1;
a[2][1] := 1; a[2][2] := 2;
k := 2;
while (k > n) do
begin
Down(k); Right(k); Copy(k);
k := k*2;
end;

a[n][n] := 0;
end;
procedure ToCenter(k: integer); { Dch trng (c,d) v tm }
var nd, nc, i: integer;
begin
nd := d + sx; nc := c + sy; k := k div 2;
for i := 1 to k do
begin
a[nd][nc] := a[nd+dx][nc+dy];
nd := nd + dx; nc := nc + dy;
a[nd][nc] := 0;
end;
d := d + k*dx; c := c + k*dy; { Chnh li ta (c,d) }
end;
{ Manh chua (x,y) trong hinh [1..n,1..n].
0 1
2 3 }
function Quater(n, x, y: integer): integer;
var q, n2: integer;
begin
q := 0; n := n div 2;
if (x > n) then q := q + 2;
if (y > n) then q := q + 1;
Quater := q;
end;
procedure NewPos(n: integer); { ta mi ca (x,y) v (c,d) }
begin
if (x > n) then x := x - n;
if (y > n) then y := y - n;
if (d > n) then d := d - n;
if (c > n) then c := c - n;
case qxy of
1: sy := sx + n;
2: sx := sy + n;
3: begin sx := sx + n; sy := sy + n; end;
end;
end;
{ doi cho a[x][y] va a[u][v] }
procedure ISwap(x, y, u, v: integer);
var t: integer;
begin
t := a[sx+x][sy+y]; a[sx+x][sy+y] := a[sx+u][sy+v];
a[sx+u][sy+v] := t;
end;
procedure Equalize(k: integer); { a (c,d) v cng mnh vi (x,y) }
var k2: integer;
begin
k2 := k div 2;
if d = k then dx := -1 else dx := 1;
if c = k then dy := -1 else dy := 1;
ToCenter(k); { d, c den vi tri moi; a[d][c] = 0 }
case qdc of
0: if (qxy = 1) then
begin
ISwap(d,c,k2,k2+1);
d := k2; c := k2+1;
end else if (qxy = 2) then
begin
ISwap(d,c,k2+1,k2);
d := k2+1; c := k2;
end;
1: if (qxy = 0) then
begin

ISwap(d,c,k2,k2);
d := k2; c := k2;
end else if (qxy = 3) then
begin
ISwap(d,c,k2+1,k2+1);
d := k2+1; c := d;
end;
2: if (qxy = 0) then
begin
ISwap(d,c,k2,k2);
d := k2; c := d;
end else if (qxy = 3) then
begin
ISwap(d,c,k2+1,k2+1);
d := k2+1; c := d;
end;
3: if (qxy = 1) then
begin
ISwap(d,c,k2,k2+1);
d := k2; c := k2+1;
end else if (qxy = 2) then
begin
ISwap(d,c,k2+1,k2);
d := k2+1; c := k2;
end;
end { case };
qdc := qxy;
end;
procedure Move;
var k: integer;
begin
k := n; d := n; c := n;
sx := 0; sy := 0;
while (k > 2) do
begin
if (x = d) and (y = c) then exit;
qdc := Quater(k,d,c); { manh chua (d,c) }
qxy := Quater(k,x,y);
{ manh chua (x,y) }
if (qdc <> qxy) then
{ chinh dong d va cot c cho cung manh voi (x,y) }
Equalize(k);
k := k div 2; NewPos(k);
end;
{ k = 2. Final }
ISwap(d,c,x,y);
end;
procedure WriteResult;
var i, j: integer;
g: text;
begin
ReadData;
assign(g,gn); rewrite(g);
writeln(g,n); writeln(g, x, bl, y); writeln(g, colors);
for i := 1 to n do
begin
writeln(g);
for j := 1 to n do write(g,a[i][j],bl);
end;
close(g);
end;
procedure Run;
begin
ReadData;

Fill; Move;
if (n = 2) then colors := 1 else colors := 3;
WriteResult;
end;
BEGIN
Run;
writeln(nl,' Fini');
readln;
END.
// DevC++: square.cpp
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L E
const int mn = 101; // kich thuoc toi da cua nen nha
const char * fn = "square.inp";
const char * gn = "square.out";
const char bl = ' ';
int a[mn][mn]; // nen nha
int n; // chieu dai nen nha
int x, y; // vi tri lo thoat nuoc;
int colors; // so mau
int sx,sy; // goc tren trai cua manh dang xet
int d,c; // dong (d) va cot (c) chua o trong
int qdc, qxy; // qdc: manh chua o trong d c; qxy: manh chua o x y
int dx, dy; // huong dich chuyen o trong
// P R O T O T Y P E S
void ReadData(); // doc du lieu: n, x, y
void Fill(); // lat nen nha
void Move(); // di chuyen o trong tu vi tri (d,c) den vi tri (x,y)
void WriteResult(); // Ghi file
void Down(int);// Lat len
void Right(int);// Lat phai
void Copy(int); // dich cheo
void Run();
void ToCenter(int); // di chuyen o trong den giua manh
int Quater(int n, int x, int y);// manh phan tu chua o (x,y) trong
manh nxn
void NewPos(int); // toa do moi
void Equalize(int);// can bang 2 manh
void ISwap(int, int, int, int);
// I M P L E M E N T A T I O N
int main() {
Run();
cout << endl << " Fini" << endl;
cin.get();
return 0;
}
void ReadData() {
ifstream f(fn);
f >> n >> x >> y;
f.close();
}
void Down(int k) { // Lt xung
int i,ii = k, j, k2 = k*2;
for (i = k+1; i <= k2; ++i,--ii)
for (j = 1; j <= k; ++j)
a[i][j] = 4-a[ii][j];
}
void Right(int k) { // Lt phi
int i, j, jj = k, k2 = 2*k;

for (j = k+1; j <= k2; ++j,--jj)


for (i = 1; i <= k; ++i)
a[i][j] = 4 - a[i][jj];
}
void Copy(int k) { // Dch cho
int i, j ;
for (i = 1; i <= k; ++i)
for (j = 1; j <= k; ++j)
a[i+k][j+k] = a[i][j];
}
void Fill() { // Lt nn nn
int k;
a[1][1] = a[1][2] = a[2][1] = 1;
a[2][2] = 2;
for (k = 2; k < n ; k *= 2) {
Copy(k); Right(k); Down(k);
}
a[n][n] = 0;
}
void ToCenter(int k) { // a (c,d) v tm
int nd = d+sx, nc = c+sy;
k = k/2;
for (int i = 1; i <= k; ++i) {
a[nd][nc] = a[nd+dx][nc+dy];
nd += dx; nc += dy;
a[nd][nc] = 0;
}
d += k*dx; c += k*dy; // ta mi ca (c,d)
}
// Manh chua (x,y) trong hinh [1..n,1..n]
// 0 1
// 2 3
int Quater(int n, int x, int y) {
int q = 0;
n /= 2;
if (x > n) q += 2;
if (y > n) ++q;
return q;
}
void NewPos(int n) {// Cp nht ta (x,y) v (c,d)
if (x > n) x -= n;
if (y > n) y -= n;
if (d > n) d -= n;
if (c > n) c -= n;
switch(qxy) {
case 1: sy += n; break;
case 2: sx += n; break;
case 3: sx += n; sy += n; break;
}
}
// doi cho a[x][y] va a[u][v]
void ISwap(int x, int y, int u, int v) {
int t = a[sx+x][sy+y]; a[sx+x][sy+y] = a[sx+u][sy+v];
a[sx+u][sy+v] = t;
}
void Equalize(int k) { // di chuyen o trong (d,c)
// den manh chua qxy
int k2 = k/2;
dx = (d == k) ? -1 : 1;
dy = (c == k) ? -1 : 1;
ToCenter(k); // d, c den vi tri moi; a[d][c] = 0
switch(qdc) {
case 0: if (qxy==1) {

ISwap(d,c,k2,k2+1);
d = k2; c = k2+1;
}
else if (qxy==2) {
ISwap(d,c,k2+1,k2);
d = k2+1; c = k2;
};
break;
case 1: if (qxy==0) {
ISwap(d,c,k2,k2);
d = c = k2;
}
else if (qxy==3) {
ISwap(d,c,k2+1,k2+1);
d = c = k2+1;
};
break;
case 2: if (qxy==0) {
ISwap(d,c,k2,k2);
d = c = k2;
}
else if (qxy==3) {
ISwap(d,c,k2+1,k2+1);
d = c = k2+1;
};
break;
case 3: if (qxy==1) {
ISwap(d,c,k2,k2+1);
d = k2; c = k2+1;
}
else if (qxy==2) {
ISwap(d,c,k2+1,k2);
d = k2+1; c = k2;
};
break;
}
qdc = qxy;
}
void Move() {
int k;
k = d = c = n;
sx = sy = 0;
while (k > 2) {
if (x==d && y == c) return;
qdc = Quater(k,d,c); // manh chua (d,c)
qxy = Quater(k,x,y); // manh chua (x,y)
if (qdc != qxy)
// chinh dong d va cot c cho cung manh voi (x,y)
Equalize(k);
k /= 2; NewPos(k);
}
// k = 2. Final
ISwap(d,c,x,y);
}
void WriteResult() {
ReadData();
ofstream g(gn);
g << n ;
g << endl << x << bl << y;
g << endl << colors;
int i,j;
for (i = 1; i <= n; ++i) {
g << endl;

for (j = 1; j <= n; ++j)


g << a[i][j] << bl;
}
g.close();
}
void Run() {
ReadData();
Fill();
Move();
colors = (n == 2) ? 1 : 3;
WriteResult();
}

4.8 Test
Bn hy gip Ban Gim kho cuc thi vit mt chng trnh kim tra bi gii Lt nn 2 ni trn. D liu
vo chnh l output file square.out. D liu ra ghi trong output file test.out cc thng tin sau y:
0 nu kt qu ng;
1 nu t sai l thot nc;
2 nu t gch sai;
3 nu s mu cng b khc vi s mu thc lt.
Thut ton
Trc ht m file square.out c thng tin bao gm cc gi tr: n chiu di cnh ca nn nh; (x,y) v tr
(dng, ct) ca trng; colors s mu dng. Tip n c d liu kt qu v nn nh lt vo mng
hai chiu a ri chuyn qua pha kim li.
Nu a[x][y] 0 ta ghi nhn li 1: t sai l thot nc;
Vi mi (i,j) trn nn nh ta gi th tc Loang(i,j,c,d), trong c l mu ca (i,j), c = a[i][j].
Th tc ny nh du v m s cng mu c v lin thng cnh vi (i,j). Gi s m c l s. Ta
xt:
Nu s > 3 tc l c hn hai vin gch ch L cng mu v k cnh nhau, v mi vin gch ch L ch c
php chim ti a 3 cng mu. Trng hp ny ta ghi li 2: t gch sai.
Nu s = 3 nhng 3 cng mu nm thng hng th bo li 2: t gch sai.
Th tc Loang cn m nhim thm chc nng tch ly vo bin d s mu gch lt khc nhau dng. Nu
d colors ta ghi nhn li 3: s mu thc dng khc vi s mu cng b.
Khi loang ta nh du xt bng gi tr i ca n.
(* tsquare.pas *)
uses crt;
const mn = 100; bl = #32; nl = #13#10;
gn = 'square.out'; hn = 'test.out';
type mi1 = array[0..mn] of integer;
mi2 = array[0..mn] of mi1;
var
a: mi2;
n, x, y, colors: integer;
procedure Loang(i, j, c: integer; var d: integer);
begin
if (a[i][j] <> c) then exit;
a[i][j] := -a[i][j]; inc(d);
Loang(i+1,j,c,d);
Loang(i-1,j,c,d);
Loang(i,j+1,c,d);
Loang(i,j-1,c,d);
end;
(*
0: khong co loi
1: Dat sai lo thoat
2: Dat sai gach
3: sai so mau
*)
procedure Test;
var i, j, c, dc, d: integer;
g,h: text;

col: mi1; { danh dau so mau da dung }


begin
assign(g,gn); reset(g);
read(g,n,x,y,colors);
write(nl,' n = ', n, ' x = ', x, '
y = ', y);
fillchar(a,sizeof(a),0); fillchar(col,sizeof(col),0);
for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
read(g,a[i][j]); write(a[i][j],bl);
end;
end;
close(g);
writeln;
assign(h,hn); rewrite(h); dc := 0;
if (a[x][y] <> 0) then
begin writeln(h,1); close(h); exit; end;
for i := 1 to n do
for j := 1 to n do
begin
c := a[i][j];
if (c > 0) then
begin
if (col[c] = 0) then
begin col[c] := 1; inc(dc) end;
d := 0; Loang(i,j,c,d);
if (d <> 3) then
begin writeln(h,2); close(h); exit end;
{ d = 3: xet 3 phan tu lien tiep }
if ( (a[i][j]=a[i][j+1])and(a[i][j]=a[i][j+2]) )
or ( (a[i][j]=a[i+1][j])and(a[i][j]=a[i+2][j]) )
then begin writeln(h,2); close(h); exit end;
end;
end ; { for }
if (d <> colors) then begin writeln(h,3); close(h); exit end;
writeln(h,0); close(h);
end;
BEGIN
Test;
writeln(nl,' Fini');
readln;
END.
// DevC++: tsquare.cpp
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L E
const int mn = 101;
const char * gn = "square.out";
const char * hn = "test.out";
const char bl = ' ';
int a[mn][mn];
int n, x, y, colors;
// P R O T O T Y P E S
void Test();
void Loang(int, int, int, int& );
// I M P L E M E N T A T I O N
int main() {
Test();

cout << endl << " Fini" << endl;


cin.get();
return 0;
}
/*
0: khong co loi
1: Dat sai lo thoat
2: Dat sai gach
3: sai so mau
*/
void Test() {
ifstream g(gn);
g >> n >> x >> y >> colors;
cout << endl << " n = " << n << ", x = " << x << ", y = " << y
<< ", colors = " << colors << endl;
int i, j, c, dc, d; // dc dem so mau
int col[100]; // danh dau mau da dung
memset(a,0,sizeof(a)); memset(col,0,sizeof(col));
for (i = 1; i <= n; ++i) {
cout << endl;
for (j = 1; j <= n; ++j) {
g >> a[i][j]; cout << a[i][j] << bl;
}
}
g.close();
cout << endl;
ofstream h(hn); dc = 0;
if (a[x][y] != 0) { h << 1; h.close(); return; }
for (i = 1; i <= n; ++i)
for (j = 1; j <= n; ++j) {
c = a[i][j];
if (c > 0) {
if (col[c] == 0) {col[c] = 1; ++dc; } // them mau moi
d = 0; Loang(i,j,c,d);
if (d != 3) { h << 2; h.close(); return; }
// d = 3: xet 3 phan tu lien tiep
if ( ( (a[i][j]==a[i][j+1])&&(a[i][j]==a[i][j+2]) )
|| ( (a[i][j]==a[i+1][j])&&(a[i][j]==a[i+2][j]) ) )
{ h << 2; h.close(); return; }
}// if c > 0
}// for j
if (d != colors) { h << 3; h.close(); return; }
h << 0;
h.close();
}
void Loang(int i, int j, int c, int &d) {
if (a[i][j] != c) return;
a[i][j] = -a[i][j]; ++d;
Loang(i+1,j,c,d);
Loang(i-1,j,c,d);
Loang(i,j+1,c,d);
Loang(i,j-1,c,d);
}

4.9 Gii m

Cho m nh phn ca n ch ci u bng ch ting Anh A, B, C,.... Bit rng khng c m no l khc u
ca m khc v chiu di ti a ca mi m l 10. Lp chng trnh gii m mt vn bn cho trc.
Input text file: code.inp
Dng u tin: s n; 1 n 26.
Tip n l n dng, mi dng cha m nh phn ca mt ch ci theo trt t A, B, C,...
Cui cng l dng cha m cn gii.
Output file: code.out cha vn bn gii.
code.inp
5
0000
0001
0010
0011
110
0000000100010000

code.out
ABBA

h
0

0
1

0
0
A

1
B

Th d trn cho m ca n = 5 k t u trong bng ch ci ting Anh l A = 0000, B = 0001, C =


0010, D = 0011 v E = 110. on m vn bn cn gii l s = 0000000100010000. Sau khi gii
m ta phi thu c kt qu: ABBA.
Thut ton
Trc ht ta xy dng cy nh phn h vi cc nhnh tri ng vi gi tr 0 ca mi m, nhnh phi ng vi
gi tr 1. Ti cc l ca cy ta ghi k t tng ng ca m . Nh vy, dy nhn trn mi ng i t gc
cy h n l ca h s lp thnh m ca k t trn l. Th d, ng i 0011 s kt thc ti l D, do 0011
l m nh phn ca D.
Sau da vo dy bit 0/1 ca m vn bn s ta gii m thng qua php duyt cy h nh sau:
Duyt cy h gii m vn bn
1. Xut pht t gc h.
2. Duyt ln lt mi bit si. xt 2 tnh hung:
2.1 Nu si = 0: r tri;
Nu si = 1: r phi.
2.2 Nu gp l th:
- Ghi k t trn l vo kt qu;
- Quay li gc h.
3. end.
Ta c th ci t nhanh bng cch s dng heap (chm, ng) thay cho cy. Trong bi ny ta hiu heap h l
mt cy nh phn y (gi l cy cn bng hon ton). Nu gi nh u tin ca h l 1 th hai nh k
ca n s nhn m s l 2 v 3..., tng qut, hai nh k ca nh i s c m s 2i v 2i+1, trong ta qui
nh nhnh i 2i s l nhnh tri, do nhn nhn 0; nhnh i 2i+1 l nhnh phi, do nhn nhn 1.
Nu di ti a ca m l k th heap s c 2k+11 phn t. Tht vy, do heap c k nhnh tnh t gc n l
nn s c k+1 mc vi s lng nh theo tng mc ln lt l 1, 2, 4,, 2i,, 2k. Tng s nh ca heap
khi l
1 + 2 + 22 + + 2k = 2k+1 1
p dng cng thc trn cho di max ca m k = 10 ta tnh c s phn t ca heap s l 2111 = 2047.
Nh vy ta c th s dng mt mng h cha cc nh ca cy. Th tc to cy trn heap khi s kh
n gin.
To cy h nh mt cy con ca heap

1. Khi tr mi phn t ca mng h bng 0 vi ngha


h[i] = 0: nh i l nh trung gian hoc khng thuc
cy;
h[i] = C: nh i l l v ng i t gc n nh i s
l m ca k t C.
2. Vi mi m (u1, u2,,um) ca k t C ta xt
2.1 Gi v l s hiu ca nh trong cy h.
Khi tr v := 1;
2.2 Vi mi bit ui xt.
Nu ui = 0: tnh v := 2*v;
Nu ui = 1: tnh v := 2*v + 1;
3.2 Gn h[v] := C.
3. end.
V th tc gii m trn heap h khi s l:
Gii m s trn heap h
. Xut pht t gc h vi v := 1.
2. Vi mi bit si ca m vn bn s xt:
2.1 Nu si = 0: tnh v := 2*v ;
Nu si = 1: tnh v := 2*v + 1.
2.2 Nu h[v] 0 tc l gp l th:
- Ghi k t trn l vo kt qu;
- Quay li gc h: t v := 1.
3. end.

1
0

2
0

3
0

4
0

5
0

6
0

7
0

8
0

9
0

10
0

11
0

12
0

13
0

14
E

15
0

16
A

17
B

18
C

19
D

Heap h thu c sau khi c d liu


phc tp
C n m cho n k t, mi m c duyt 1 ln to heap. Gi chiu di ti a ca m l k. Vy to
heap ta cn n.k thao tc. gii m ta duyt mi bit trong bn m 1 ln trn cy nh phn. Vy khi gii m
ta cn m = len(s) thao tc trn cy nh phn. Thao tc trn cy nh phn v nh cn log 2(v) = k php so snh.
Tng hp li, tnh theo chiu di m ca m vn bn ta cn mk php so snh.
Chng trnh
(* code.pas *)
uses crt;
const fn = 'code.inp'; gn = 'code.out';
mn = 2050; bl = #32; nl = #13#10;
var h: array[0..mn] of char;
procedure Decode;
var i, j, v, n: integer;
ch: char;
f,g: text;
x: string;
begin
ch := 'A';
assign(f,fn); reset(f);
assign(g,gn); rewrite(g);
readln(f,n); writeln(n,nl,nl);
fillchar(h,sizeof(h),0);
{Tao heap h }
for i := 1 to n do

begin
readln(f,x); writeln(x);
v := 1;
for j := 1 to length(x) do
if x[j] = '0' then v := v*2 else v := v*2 + 1;
h[v] := ch; inc(ch);
end;
writeln(nl);
for i := 1 to mn do
if (h[i] <> #0) then writeln(i,bl,h[i]);
v := 1; { Giai ma }
while not eof(f) do
begin
read(f,ch);
if (ch = '0') or (ch = '1') then
begin
v := 2*v;
if ch = '1' then v := v+1;
if (h[v] <> #0) then
begin
write(g,h[v]);
v := 1;
end;
end;
end;
close(f); close(g);
end;
BEGIN
Decode;
writeln(nl, ' Fini ');
readln;
END.
// DevC++: code.cpp
#include <iostream>
#include <fstream>
using namespace std;
const char * fn = "code.inp";
const char * gn = "code.out";
const int mn = 2050;char h[mn]; // heap
int main();
void Decode();
int main() {
Decode();
cout << endl << " Fini ";
cin.get();
return 0;
}
void Decode() {
int i, j, v, n;
char x[15]; // doan ma
char ch = 'A';
ifstream f(fn); f >> n; cout << endl << n;
f.getline(x,mn,'\n');
ofstream g(gn);
memset(h,0,sizeof(h));
cout << endl << endl;
// To heap h
for (i = 0; i < n; ++i) {
f.getline(x,mn,'\n'); cout << endl << x;
v = 1;
for (j = 0; x[j]; ++j)

v = (x[j]=='0') ? 2*v : 2*v+1;


h[v] = ch; ++ch;
}
cout << endl << endl;
// Gii m
v = 1;
while (!f.eof()) {
f >> ch;
if (ch == '0' || ch == '1') {
cout << ch;
v = (ch=='0') ? 2*v : 2*v+1;
if (h[v] != 0) {
g << h[v];
v = 1;
}
}
}
f.close(); g.close();
}

Chng 5 Luyn tp t cc thi

5.1 S nguyn t cng cao


Olimpic Duy Tn 2009
cao ca mt s t nhin l tng cc ch s ca s . Vi mi cp s t nhin n v h cho trc hy lit
k cc s nguyn t khng vt qu n v c cao h, 10 n 1000000; 1 h 54.
hprimes.inp
n h

hprimes.out
mi dng 1 s

D liu test
n = 1000, h = 16. Kt qu 15 s nguyn t cao 16: 79, 97, 277,
349, 367, 439, 457, 547, 619, 673, 691, 709, 727, 853, 907.
Thut ton
Thut ton lit k cc s nguyn t cao h trong khong 1..n
1. Gi th tc Sang(n) (do Eratosthenes xut, xem Tp 2)
xc nh cc s nguyn t trong khong 1..n
v nh du vo mng byte p: p[i] = 0 khi v ch khi i l s nguyn t.
2. Duyt li cc s nguyn t i trong danh sch p, tnh cao ca s i.
Nu Height(i) = h th ghi nhn.
3. end.
tnh cao ca s i ta tch dn cc ch s hng n ca i bng php chia d cho 10 ri cng dn vo
mt bin tng.
phc tp
Th tc sng duyt
php gn).

n ln, mi ln li duyt n phn t do cn c n n thao tc c s (php nhn,

Chng trnh
(* Hprimes.pas So nguyen to cung do cao *)
uses crt;
const fn = 'hprimes.inp'; gn = 'hprimes.out';
nl = #13#10; bl = #32; mn = 1000000;
type mb1 = array[0..mn] of byte;
var p: mb1;
n,h: longint;
procedure Sang(n: longint);
var i,j: longint;
begin
fillchar(p,sizeof(p),0);
for i := 2 to round(sqrt(n)) do
if (p[i] = 0) then
for j := i to (n div i) do p[i*j] := 1;
end;
function Height(x: longint): integer;
var sum : integer;
begin
sum := 0;
while x <> 0 do
begin
sum := sum + (x mod 10);
x := x div 10;
end;

Height := sum;
end;
procedure Ghi;
var i: longint;
G: text;
begin
assign(g,gn); rewrite(g);
for i := 2 to n do
if p[i] = 0 then
if Height(i) = h then writeln(g,i);
close(g);
end;
procedure Doc;
var f: text;
begin
assign(f,fn); reset(f);
readln(f,n,h); close(f);
end;
BEGIN
Doc; Sang(n); Ghi;
writeln(nl,' Fini'); readln;
END.
// DevC++: hprimes.cpp - So nguyen to cung do cao
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
// D A T A A N D V A R I A B L E
const int mn = 1000001;
char p[mn];
int n, h;
const char * fn = "hprimes.inp";
const char * gn = "hprimes.out";
// P R O T O T Y P E S
void Doc();
void Sang();
void Ghi();
int Height(int x);
// I M P L E M E N T A T I O N
int main() {
Doc(); Sang(); Ghi();
cout << endl << endl << " Fini" << endl;
return 0;
}
void Doc() {
ifstream f(fn);
f >> n >> h;
f.close();
}
// Sang Eratosthenes
void Sang() { // p[i] = 0 <=> i nguyen to
int can = (int) sqrt(n);
int i, j, ni;
memset(p,0,sizeof(p));
for (i = 2; i <= can ; ++i)
if (p[i] == 0)
for (ni = n/i, j = i; j <= ni; ++j)
p[i*j] = 1;
}
int Height(int x) { // tong so bit 1 cua x

int d = 0;
for (; x ; x /= 10) d += (x % 10);
return d;
}
void Ghi() {
int i;
ofstream g(gn);
for (i = 2; i <= n; ++i)
if (p[i] == 0)
if (Height(i) == h)
g << endl << i;
g.close();
}

5.2 S nguyn t cng s bt 1


Olimpic i hc K thut Cng ngh Tp HCM 2009
Vi mi n v h cho trc hy cho bit c bao nhiu s nguyn t khng vt qu n v dng nh phn
cha ng h bit 1, 10 n 1000000; 1 h 30.
bprimes.inp
100 4

bprimes.out
7

Gii thch
C 7 s nguyn t trong khong 1..100
cha ng h = 4 bit 1. l 23 = 101112 ;
29 = 111012 ; 43 = 1010112 ; 53 = 1101012;
71 =10001112; 83 = 10100112 ; 89 =10110012.

Bi ny l dng c bit ca bi trc v trong dng nh phn (ch cha cc ch s 0/1) th tng cc ch s
chnh l s bit 1. Th tc Sum di y tnh tng cc ch s ca s t nhin x khi biu din x theo dng h
s b bt k, b > 1. Nh vy, tnh tng cc ch s ca x trong h m 10 ta gi Height(x,10). Nu
cn tnh tng cc bt 1 ca x ta gi Height(x,2).
(* Pascal *)
function Height(x: longint, b: integer): integer;
var sum : integer;
begin
sum := 0;
while x <> 0 do
begin
sum := sum + (x mod b);
x := x div b;
end;
Height := sum;
end;
// DevC++
int Height(int x, int b) {
int d = 0;
for (; x ; x /= b) d += (x % b);
return d;
}
Chng trnh gii bi ny ging nh bi trc ngoi tr thay i nh l thay li gi hm mt tham s
Height(x) bng li gi 2 tham s Height(x,2).
D liu test
n = 100, h = 4: 7
n = 1000000, h = 11:
n = 1000, h = 4: 29

14176

5.3 Ct hnh
Vit Nam, 2008

Mt tm ba dng li vung cnh di n = 2k to bi cc vung n v nh s theo dng 1.. n tnh t


trn xung v theo ct 1..n tnh t tri sang. Ngi ta thc hin ln lt hai thao tc an xen nhau sau y
cho n khi nhn c mt ct gm n2 vung n v:
1. Ct ngang hnh theo ng k gia sau chng na trn ln trn na di;
2. Ct dc hnh theo ng k gia sau chng na tri ln trn na phi.
Ti ct cui cng ngi ta nh s cc vung n v 1, 2,..., n2 tnh t trn xung.
Hy vit hai th tc sau y
a) ViTri(k, i, j) = v cho ra s th t v ca (i,j) trn ct cui cng.
b) ToaDo(k, v, i, j) Cho trc k v v tr v trn ct cui cng, tnh ta (i,j) ca ban
u.
Th d
ViTri(2, 4, 3) = 8.
ToaDo(2,8,i, j) cho kt qu i = 4, j = 3.
Thut ton
Ta kho st bi ton vi k = 2. Ta c n = 2k = 22 = 4. Ta k hiu nm trn dng i, ct j l [i,j].
Nhn xt: Ta gi mt ln ct ngang v mt
ln ct dc lin tip nhau l ND. Sau mi ln
A
C
[1,1] [1,2] [1,3] [1,4]
ND ta thu c 4 mnh vung v bng nhau
Tng 1
[2,1] [2,2] [2,3] [2,4]
A, B, C v D c chng ln nhau thnh mt
[3,1] [3,2] [3,3] [3,4]
ct theo th t tnh t trn xung l A, B, C
[4,1] [4,2] [4,3] [4,4]
B
D
v D (mnh A trn cng, mnh D di cng).
Gi d l dy (s tng) ca khi ny. Ta c,
4 mnh thu
Trc khi ct ct c duy nht
lc u d = 1 v ct ch c 1 tng gm 1 tm
c sau mt
1 tng
ba duy nht ban u. Gi n l chiu di cnh
ln ND
ca mt mnh hnh vung. Sau mi ln ND, n
gim 2 ln. V tr v ca cc n v trong mnh A s c bo lu, trong mnh B c cng thm d,
mnh C c cng thm 2d v mnh D c cng thm 3d. Sau mi ln ND s tng d s tng thm 4 ln.
Bit ta (i,j) trong hnh ABCD ta d dng tnh c ta mi (i',j') trong tng mnh.
Tng 1: A

Tng 1

[1,1] [1,2] [1,3] [1,4]


[2,1] [2,2] [2,3] [2,4]
AC

Tng 2

[3,1] [3,2] [3,3] [3,4]


[4,1] [4,2] [4,3] [4,4]
BD
Ct ngang ln 1 v chng na trn ln trn na di
thu c 2 tng

Tng 1
Tng 2
Tng 3
Tng 4
Tng 5
Tng 6
Tng 7
Tng 8

[1,1] [1,2]
[3,1] [3,2]
[1,3] [1,4]
[3,3] [3,4]
[2,1] [2,2]
[4,1] [4,2]
[2,3] [2,4]
[4,3] [4,4]

Ct ngang ln 2 v chng na trn ln trn na


di thu c 8 tng

[1,1] [1,2]
[2,1] [2,2]
Tng 2: B
[3,1] [3,2]
[4,1] [4,2]
Tng 3: C
[1,3] [1,4]
[2,3] [2,4]
Tng 4: D
[3,3] [3,4]
[4,3] [4,4]
Ct dc ln 1 v chng na tri ln trn na phi
thu c 4 tng

Tng 1
Tng 2
Tng 3
Tng 4
Tng 5
Tng 6
Tng 7
Tng 8
Tng 9
Tng 10
Tng 11
Tng 12
Tng 13
Tng 14
Tng 15
Tng 16

[1,1]
[3,1]
[1,3]
[3,3]
[2,1]
[4,1]
[2,3]
[4,3]
[1,2]
[3,2]
[1,4]
[3,4]
[2,2]
[4,2]
[2,4]
[4,4]

Ct dc ln 2 v chng na tri ln trn na phi


Ta chn cch m s cc mnh A, B, C v D mt cch khn ngoan. C th l ta gn m s cho cc mnh ny
theo s ln cng thm dy d sau mi ln ND, tc l ta t A = 0, B = 1, C = 2 v D = 3. Trong dng nh
phn ta c A = 002, B = 012, C = 102 v D = 112.

A
002 = 0

C
102 = 2

B
012 = 1

D
112 = 3

Sau mi ln ND ta thu
c 4 mnh A, B, C, D.

function ViTri(k,i,j: integer): integer;


var d, v, m, manh, n: integer;
begin
d := 1; { so tang }
v := 1; { tang chua o [i,j] }
n := 1 shl k; { n = 2^k }
for m := 1 to k do
begin
n := n div 2; manh := 0;
if (j > n) then
begin
manh := 2; j := j - n;
end;
if (i > n) then
begin
manh := manh + 1; i := i - n;
end;
v := v + manh*d; d := 4*d;
end;
ViTri := v;
end;

Th tc ToaDo l i xng vi th tc ViTri.


procedure ToaDo(k,v: integer; var i,j: integer);
var n,nn,m,d, manh: integer;
begin
n := 1 shl k; d := n*n;
n := 1 ; { kich thuoc 1 tang }
i := 1; j := 1;
for m := 1 to k do
begin
d := d div 4;
manh := (v-1) div d;
if (manh >= 2) then j := j+n;
if odd(manh) then i := i+n;
v := v - manh*d; n := n * 2;
end;
end;
// DevC++
#include <iostream>
using namespace std;
// P R O T O T Y P E S
int ViTri(int, int, int);
void ToaDo(int, int, int &, int &);
void Test(int);
// I M P L E M E N T A T I O N
int main() {
Test(2);
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
// Cho biet k va toa do (i,j). Tim vi tri tren cot
int ViTri(int k, int i, int j) {

int n = 1 << k; // kich thuoc hinh: n = 2^k


int d = 1; // be day 1 tang
int v = 1; // vi tri;
int manh;
for (int m = 0; m < k; ++m) {
n >>=1; // n = n/2
manh = 0;
if (j > n) { manh = 2; j -= n; }
if (i > n) { manh += 1; i -= n; }
v += manh * d; d *= 4;
}
return v;
}
// Cho vi tri o tren cot v, tinh toa do (i,j). n = 2^k
void ToaDo(int k, int v, int &i, int &j) {
int n = 1, d = 1 << k, manh = 0;
d *= d;
i = j = 1;
for (int m = 0; m < k; ++m) {
d >>= 2; // d /= 4;
manh = (v - 1) / d;
if (manh >= 2) j += n;
if (manh % 2 == 1) i += n;
v -= manh * d; n *= 2;
}
}
phc tp
Vi n = 2k chng trnh cn k ln lp, mi ln lp cn thc hin khng qu 10 php ton s hc trn cc s
nguyn.
Th tc Test di y hin th v tr v ca mi (i,j), i = 1..n, j = 1..n sau xut pht t v tr v tnh li
ta i, j.
(* Pascal *)
procedure Test(k: integer);
var n, v, ii, jj : integer;
begin
n := 1 shl k; { n = 2^k }
writeln; writeln( ' k = ', k, ' n = ', n);
for i := 1 to n do
for j := 1 to n do
begin
v := ViTri(k, i, j); ToaDo(k, v, ii, jj);
writeln; write('(',i, ',', j, ') => ', v);
writeln(' => ', '(', ii, ',', jj, ')');
readln;
end;
end;
// DevC++
void Test(int k) {
int n = 1 << k;
cout << endl << "k = " << k << " n = " << n
int v, ii, jj;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j) {
v = ViTri(k, i, j); ToaDo(k, v, ii, jj);
cout << endl << "(" << i << "," << j << ") => "
<< v << " => (" << ii << "," << jj << ")";
cin.get();
}
}

5.4 Tng nh nht

Vit Nam, 2008


Cho hai dy s nguyn ai v bi, i = 1, 2, ..., n cha cc ga tr trong khong -1 t n 1 t,
1 n 1000. Tm gi tr nh nht ca ||ai+bj||, 1 i, j n.
MINSUM.INP
5
7 5 1 -3 6
8 9 1 5 -9

MINSUM.OUT
2

Thut ton
Trc ht ta sp tng hai dy a v b. Sau , vi mng a ta duyt xui theo ch s i bin thin t 1..n, vi
mng b ta duyt ngc theo ch s j bin thin t n v 1. t t(i,j) = ai + bj ta c nhn xt sau:
1. t l mt hm 2 bin theo i v j,
2. Nu c nh i, cho j gim dn th t l hm ng bin theo j, ngha l t(i,j) t(i,j') nu j > j'.
3. Nu c nh j th t l hm ng bin theo i, ngha l t(i,j) t(i',j) nu i < i'.
T nhn xt trn ta suy ra chin lc tm kim tr nh nht ca ||t(i,j)|| trong hm XuLi nh sau:
- Nu t(i,j) = 0 ta nhn gi tr ny v kt thc thut ton.
- Nu t(i,j) < 0 ta cn tng gi tr ca hm ny bng cch tng i thm 1 n v.
- Nu t(i,j) > 0 ta cn gim gi tr ca hm ny bng cch gim j bt 1 n v.
Sau mt s bc lp ta gp tnh hung, hoc i = n hoc j = 1. Ta x l tip nh sau:
- Nu i = n, ta cn duyt nt phn cn li b[j..1], ngha l tnh t(n,k) vi k = j..1. V y l hm
ng bin nn khi t(n,k) 0 ta dng thut ton.
- Tng t, nu j = 1, ta cn duyt nt phn cn li ca a[j..n], ngha l tnh t(k,1) vi k = i..n. V
y l hm ng bin nn khi t(k,1) 0 ta cng dng thut ton.
Ti mi bc lp ta tnh v cp nht gi tr min m ca || t ||.
phc tp
Thut ton sp xp nhanh cn n.log2(n) php so snh. Khi tnh gi tr min, mi bc lp ta thay i ng 1
trong 2 ch s i hoc j do s php so snh l 2n. Tng hp li ta cn c n.log2(n) php so snh.
Chng trnh
(* Pascal *)
const
bl = #32; nl = #13#10;
fn = 'minsum.inp';
gn = 'minsum.out';
mn = 1001;
type ml1 = array[1..mn] of longint;
var
a,b: ml1;
n: integer;
f,g: text;
procedure Print(var a: ml1; d,c: integer);
var i: integer;
begin
writeln;
for i:= d to c do write(a[i],bl);
end;
procedure Sort(var a: ml1; d, c: integer);
var i,j: integer; t,m: longint;
begin
i := d; j := c; m := a[(d+c) div 2];
while (i <= j) do
begin
while (a[i] < m) do inc(i);
while (a[j] > m) do dec(j);
if (i <= j) then
begin
t := a[i]; a[i] := a[j]; a[j] := t;
inc(i); dec(j);
end;

end;
if (d < j) then Sort(a,d,j);
if (i < c) then Sort(a,i,c);
end;
procedure Ghi(m: longint);
begin
assign(g,gn); rewrite(g);
writeln(g,m);
close(g);
end;
function XuLi: longint;
var i,j,v: integer;
t,m: longint;
begin
XuLi := 0;
Sort(a,1,n); Sort(b,1,n);
writeln(nl,'Sau khi sap tang ');
Print(a,1,n); Print(b,1,n);
i := 1; j := n; m := MaxLongInt;
while (i <= n) and (j >= 1) do
begin
t := a[i]+b[j]; v := abs(t);
if (m > v) then m := v;
if t = 0 then exit;
if (t < 0) then inc(i) else dec(j);
end;
{ i = n+1 or j = 0 }
for i := i to n do
begin
t := a[i]+b[1]; v := abs(t);
if (m > v) then m := v;
if (t >= 0) then begin XuLi := m; exit end;
end;
for j := j downto 1 do
begin
t := a[n]+b[j]; v := abs(t);
if (m > v) then m := v;
if (t <= 0) then begin XuLi := m; exit end;
end;
XuLi := m;
end;
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f);
readln(f,n);
for i := 1 to n do read(f,a[i]);
for i := 1 to n do read(f,b[i]);
close(f);
end;
procedure Run;
begin
Doc;
writeln(nl,n);
Print(a,1,n); Print(b,1,n);
Ghi(XuLi);
end;
BEGIN
Run;
readln;
END.

// DevC++
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <Math.h>
using namespace std;
// D A T A A N D V A R I A B L E
const char * fn = "minsum.inp";
const char * gn = "minsum.out";
const int mn = 1001;
int a[mn], b[mn];
int n;
// P R O T O T Y P E S
void Doc();
void Print(int [], int , int);
int XuLi();
void Ghi(int);
void Sort(int [], int, int);
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(){
Doc();
cout << endl << n;
Print(a,1,n); Print(b,1,n);
Ghi(XuLi());
}
void Ghi(int m){
ofstream g(gn);
g << m;
g.close();
}
int XuLi(){
Sort(a,1,n);
Sort(b,1,n);
cout << endl << "Sau khi sap tang ";
Print(a,1,n); Print(b,1,n);
int i = 1, j = n, m = 0x7fffffff, t, v;
while (i <= n && j >= 1){
t = a[i]+b[j]; v = abs(t);
if (m > v) m = v;
if (t == 0) return 0;
if (t < 0) ++i;
else --j;
}
// i = n+1 || j = 0
for (;i <= n; ++i){
t = a[i]+b[1]; v = abs(t);
if (m > v) m = v;
if (t >= 0) return m;
}
for (;j >= 1;--j){
t = a[n]+b[j]; v = abs(t);
if (m > v) m = v;
if (t <= 0) return m;
}
return m;

}
void Sort(int a[], int d, int c){
int i = d, j = c, m = a[(d+c)/2], t;
while (i <= j){
while (a[i] < m) ++i;
while (a[j] > m) --j;
if (i <= j) {
t = a[i]; a[i] = a[j]; a[j] = t;
++i; --j;
}
}
if (d < j) Sort(a,d,j);
if (i < c) Sort(a,i,c);
}
void Doc(){
ifstream f(fn);
f >> n;
int i;
for (i = 1; i <= n; ++i) f >> a[i];
for (i = 1; i <= n; ++i) f >> b[i];
f.close();
}
void Print(int a[], int d, int c){
int i;
cout << endl;
for (i = d; i <= c; ++i) cout << a[i] << " ";
}

5.5 L c
Vit Nam, 2008
Cho n vng trn, mi vng trn cha mt gi tr nguyn dng c th trng nhau. Gi a i l gi tr cha
trong vng trn i. Nu ba vng trn i. j, k khc nhau v tha ng thc ai+aj = ak th ta v 2 cung (c
hng) ik v jk. Cho bit ng i di nht c th qua bao nhiu nh.
loco.inp
10
4 6 5 8 1 2 3 2 3 4

loco.out
6

Gii thch Vi 10 vng trn cha cc gi


tr lit k trong file loco.inp, mt ng i
di nht qua 6 nh cha gi tr sau:

Thut ton
Sau khi c d liu vo mng a v sp tng mng a ta thy rng mi cung ik trong th c hng G xy
dng theo yu cu ca u bi lun lun km vi mt cung jk khi v ch khi a[i]+a[j] = a[k]; i j; i,j < k.
G chnh l th mt chiu (c cung hng t nh s hiu nh ti nh s hiu ln), khng chu trnh.
Ngoi ra, do dy a ch gm cc gi tr nguyn dng v c sp tng nn vi i, j cho trc th ng thc
a[i] + a[j] = a[k] ch c hy vng t c vi nhng k > max(i,j). Ta s dng mt mng d vi cc phn t
d[k] ghi nhn s nh nm trn ng di nht i n nh k. Ta c
d[k] = Max { Max(d[i]+1, d[j]+1) | 1 i < j < k, a[i] + a[j] = a[k] }
Ta khi tr cho d[k] = 1 vi mi k = 1..n vi ngha l khi ch c 1 nh c lp th ng di nht ch
cha 1 nh . Mi khi t h thc a[i]+a[j] = a[k] ta chnh li d[k] l gi tr max ca 3 gi tr: d[k],
d[i]+1 v d[j]+1, ng thi ta cng xc nh gi tr dmax cho ton bi.
Do a l dy sp tng nn vi mi k ta ch duyt cc cp nh i, j tha 1 i < j < k. Ngoi ra, tnh d[k],
vi mi i chn, tc l khi bit k v i, nu tn ti j a[i] + a[j] = a[k] th ta khng cn xt tip cc gi
tr a[j] khc.
Hm chnh ca chng trnh MaxPath hot ng nh sau:
Vi mi k = 2..n hm tnh gi tr d[k] l s nh nhiu nht trong s cc ng i kt thc ti nh k. ng
thi hm ghi nhn gi tr max ca cc d[k].
Hm Tinhd(k) thc hin chc nng tnh gi tr d[k]. Hm ny hot ng nh sau:
Phc tho thut ton tnh d[k]
Bit trc k;
Vi mi i = 1..(k1) v vi mi j = (i+1)..(k1):
Kim tra iu kin c hng: Nu a[k] = a[i]+a[j] chng t c ng i ik v

jk th ta chn ng di nht (qua i hoc j) n k v cp nht li d[k] thng qua


li gi hm d[k] := Max(d[k], d[i]+1,d[j]+1).
end.

phc tp
Ta c 3 vng lp: theo k trong hm MaxPath v 2 vng lp theo i v j trong hm Tind(k) nn phc tp
c n3.
Chng trnh
(* Loco.cpp *)
uses crt;
const
fn = 'loco.inp'; gn = 'loco.out';
mn = 10001; bl = #32; nl = #13#10;
type mi1 = array[0..mn] of integer;
var
f,g: text;
a,d: mi1;
n: integer;
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f);
readln(f,n);
for i := 1 to n do read(f,a[i]);
close(f);
end;
procedure Sort(d,c: integer);
var i, j, t, m: integer;
begin
i := d; j := c; m := a[(d+c) div 2];
while (i <= j) do
begin
while (a[i] < m) do inc(i);
while (a[j] > m) do dec(j);
if (i <= j) then
begin
t := a[i]; a[i] := a[j]; a[j] := t;
inc(i); dec(j);
end;
end;
if (d < j) then Sort(d,j);
if (i < c) then Sort(i,c);
end;
{ Max cua 3 so nguyen a, b, c }
function Max(a, b, c: integer): integer;
begin
if a < b then a := b;
if a < c then Max := c else Max := a;
end;
procedure Tinhd(k: integer);
var i,j,t: integer;
begin
d[k] := 1;
for i := 1 to k-1 do
for j := i + 1 to k - 1 do
begin
t := a[i] + a[j];
if t > a[k] then break;
if t = a[k] then
begin

d[k] := Max(d[k], d[i]+1, d[j]+1);


break;
end;
end;
end;
function MaxPath: integer;
var k, dmax: integer;
begin
MaxPath := 0;
if (n = 0) then exit;
d[1] := 1; dmax := 1;
for k := 2 to n do
begin
Tinhd(k);
if d[k] > dmax then dmax := d[k];
end;
MaxPath := dmax;
end;
procedure Ghi(m: integer);
begin
assign(g,gn); rewrite(g);
writeln(g,m); close(g);
end;
BEGIN
Doc; Sort(1,n); Ghi(MaxPath);
END.
// DevC++: Loco.cpp
#include <string.h>
#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 = "loco.inp";
const char * gn = "loco.out";
const int mn = 10001;
int a[mn], d[mn];
int n;
// P R O T O T Y P E S
void Doc();
void Sort(int, int);
int Max(int, int, int);
int MaxPath();
void Tinhd(int);
void Ghi(int);
// I M P L E M E N T A T I O N
int main(){
Doc(); Sort(1,n); Ghi(MaxPath());
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void Ghi(int m){
ofstream g(gn); g << m; g.close();
}
// Max cua 3 so nguyen a, b, c
int Max(int a, int b, int c){
if (a < b) a = b;
return (a > c) ? a : c;
}
int MaxPath(){
int k, dmax = 1;
if (n == 0) return 0;

d[1] = 1;
for (k = 2; k <= n; ++k){
Tinhd(k);
if (dmax < d[k]) dmax = d[k];
}
return dmax;
}
void Tinhd(int k){
int i, j, t;
d[k] = 1;
for (i = 1; i < k ; ++i)
for (j = i+1 ; j < k ; ++j){
t = a[i]+a[j];
if (t > a[k]) break;
if (t == a[k]){
d[k] = Max(d[k],d[i]+1,d[j]+1);
break;
}
}
}
void Doc(){
ifstream f(fn);
f >> n;
int i;
for (i=1; i <= n; ++i)
f >> a[i];
f.close();
}
void Sort(int d, int c){
int i = d, j = c, m = a[(i+j)/2];
int t;
while (i <= j){
while (a[i] < m) ++i;
while (a[j] > m) --j;
if (i <= j){
t = a[i]; a[i] = a[j]; a[j] = t;
++i; --j;
}
}
if (d < j) Sort(d,j);
if (i < c) Sort(i,c);
}
Ci tin 1
Khi tnh d[k] ta nn tm kim nh phn trn on c sp tng a[i+1..k1] nh sau. Bit trc a[k], vi
mi i ta bit a[i] v cn tm a[j] trong on a[i+1..k1] tho iu kin a[i] + a[j] = a[k]. t t = a[k] a[i],
bi ton quy v vic tm phn t a[j] = t trong on sp tng a[i+1..k1]. Nu tm c th ta cp nht d[k].
Ci tin ny gim phc tp xung cn (log n).n2.
Hm Binsearch(t,s,e) di y thc hin vic tm kim nh phn gi tr t trong on sp tng a[s..e] ca
mng a. Hm cho ra ch s j trong khong s..e nu a[j] = t; ngc li, khi khng tn ti ch s j nh vy th
hm cho ra gi tr 0. Hm Binsearch hot ng nh sau:
Phc tho thut ton cho hm Binsearch
1. Xc nh phn t m = a[(s+e)/2] l phn t gia ca on a[s..e];
2. So snh t vi m:
Nu t > m: s tm kim tip trn on t s = m+1 n e;
Nu t m: s tm kim tip trn on t s n e = m.
3. Cc bc 1 v 2 s c lp n khi s = e.
4. Khi s = e: Nu a[s] = t th return s; nu khng: return 0;
5. end.

(* Pascal: Loco, Cai tien 1 *)


uses crt;
const
fn = 'loco.inp'; gn = 'loco.out';
mn = 10001; bl = #32; nl = #13#10;
type mi1 = array[0..mn] of integer;
var
f,g: text;
a,d: mi1;
n: integer;
procedure Doc; T vit
procedure Sort(d,c: integer); T vit
function Max(a, b, c: integer): integer; T vit
{ Tim j trong khoang s..e thoa: a[j] = t }
function Binsearch(t,s,e: integer): integer;
var m: integer;
begin
Binsearch := 0;
if s > e then exit;
while (s < e) do
begin
m := (s+e) div 2;
if (a[m] < t) then s := m+1 else e := m;
end;
if (a[s] = t) then Binsearch := s else Binsearch := 0;
end;
procedure Tinhd(k: integer);
var i,j,t: integer;
begin
d[k] := 1;
for i := 1 to k-1 do
begin
t := a[k] a[i];
if (t > 0) then
begin
j := Binsearch(t, i+1, k-1);
if j > 0 then
d[k] := Max(d[k], d[i]+1, d[j]+1);
end;
end;
end;
function MaxPath: integer;
var k, dmax: integer;
begin
if (n = 0) then begin MaxPath := 0; exit end;
if (n = 1) then begin MaxPath := 1; exit end;
dmax := 1; d[1] := 1; d[2] := 1;
for k := 3 to n do
begin
Tinhd(k);
if d[k] > dmax then dmax := d[k];
end;
MaxPath := dmax;
end;
procedure Ghi(m: integer); T vit
BEGIN
Doc; Sort(1,n); Ghi(MaxPath);
END.
// DevC++, Loco.cpp: Cai tien 1

#include <string.h>
#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 = "loco.inp";
const char * gn = "loco.out";
const int mn = 10001;
int a[mn], d[mn];
int n;
// P R O T O T Y P E S
void Doc();
void Sort(int, int);
int Max(int, int, int);
int Binsearch(int, int, int);
int MaxPath();
void Tinhd(int);
void Ghi(int);
// I M P L E M E N T A T I O N
int main(){
Doc(); Sort(1,n); Ghi(MaxPath());
return EXIT_SUCCESS;
}
void Ghi(int m) t vit
int Max(int a, int b, int c) t vit
// Tim nhi phan vi tri xua hien cua x trong a[s.e]
int Binsearch(int t, int s, int e){
int m;
if (s > e) return 0;
while (s < e) {
m = (s+e) / 2;
if (a[m] < t) s = m + 1; else e = m;
}
return (a[s] == t) ? s : 0;
}
int MaxPath(){
if (n == 0) return 1;
if (n == 1) return 1;
d[1] = d[2] = 1;
int k, dmax = 1;
for (k = 3; k <= n; ++k){
Tinhd(k);
if (dmax < d[k]) dmax = d[k];
}
return dmax;
}
void Tinhd(int k){
int i, j, t;
d[k] = 1;
for (i = 1; i < k ; ++i) {
t = a[k]-a[i];
if (t > 0){
j = Binsearch(t,i+1,k-1);
if (j > 0)
d[k] = Max(d[k],d[i]+1,d[j]+1);
}
}
}
void Doc() t vit;
void Sort(int d, int c) t vit;
Ci tin 2

rng nu trong dy a c hai phn t a[i] = a[j], tc l c hai nh cha cng mt gi tr th trong kt
qu cui cng ta phi c d[i] = d[j], tc l s lng nh trn cc ng i di nht kt thc ti i v j phi
bng nhau. Tuy nhin ta phi x l trng hp a[i] = a[j], i j v tn ti k a[i]+a[j] = 2a[i] = a[k]. Khi
ta vn c 2 cung ik v jk; v d[k] d nhin cn c cp nht. Nhn xt ny cho php ta lc bt
cc ga tr trng lp ch gi li ti a hai phn t bng nhau.
Ci tin 3
Nu cc gi tr ca dy a l nh, th d nm trong khong 1.. 20000 th ta c th dng mng nh du.
Ta s m s nh bng chnh gi tr cha trong nh. Ta t s[i] = 1 nu i xut hin duy nht 1 ln trong
input file; s[i] = 2 nu i xut hin nhiu ln trong input file; ngc li, nu i khng xut hin trong dy th
ta t s[i] = 0.
1 2 3 4 5 6 7 8
i
s[i] 1 2 2 2 1 1 0 1
Mng s sau khi c d liu:
s[i] = 1 nu i xut hin duy nht 1 ln;
s[i]= 2 nu i xut hin hn 1 ln;
s[i] = 0 nu i khng xut hin trong dy.
Sau , tnh d[k] ta ch xt nhng gi tr k xut hin trong dy cho, ngha l s[k] > 0. Vi mi i =
1..k/2 ta xt, nu i v j = ki u c trong dy, tc l s[i] > 0 v s[ki] > 0 th ta t d[k] = max(d[k], d[i] +
1, d[ki] + 1). Cui cng ta xt thm trng hp k l s chn v s[k/2] = 2, ngha l k l tng ca hai s
bng nhau v c mt trong dy.
1
2
3
4
5
6
7
8
i
s[i]
1
2
2
2
1
1
0
1
d[i]
1
1
2
3
4
5
0
6
Mng d thu c sau khi x l theo s
d[i] s nh trn ng di nht kt thc ti nh i.
Ci tin ny rt phc tp tnh ton xung cn n2.
Bn lu s dng Free Pascal c min nh.
(* Loco.pas: Cai tien 3 *)
uses crt;
const
fn = 'loco.inp'; gn = 'loco.out';
mn = 20000; bl = #32; nl = #13#10;
type mi1 = array[0..mn+1] of integer;
var
f,g: text;
s,d: mi1;
n: integer;
maxv: integer; { Gia tri max trong input file }
procedure Doc;
var i,j: integer;
begin
assign(f,fn); reset(f); maxv := 0;
readln(f,n); fillchar(s,sizeof(s),0);
for i := 1 to n do
begin
read(f,j);
if (maxv < j) then maxv := j;
if s[j] > 0 then s[j] := 2 else s[j] := 1;
end;
close(f);
end;
function Max(a, b, c: integer): integer; t vit
procedure Tinhd(k: integer);
var i,k2: integer;
begin

d[k] := 1; k2 := (k-1) div 2;


for i := 1 to k2 do
if (s[i] > 0) and (s[k-i] > 0) then
d[k] := Max(d[k], d[i]+1, d[k-i]+1);
if (not odd(k)) then
begin
inc(k2);
if (s[k2] = 2) then
d[k] := Max(d[k], d[k2]+1, d[k2]+1);
end;
end;
function MaxPath: integer;
var k, dmax: integer;
begin
fillchar(d,sizeof(d),0); dmax := 0;
for k := 1 to maxv do
if s[k] > 0 then
begin
Tinhd(k);
if d[k] > dmax then dmax := d[k];
end;
MaxPath := dmax;
end;
procedure Ghi(m: integer); t vit
BEGIN
Doc; Ghi(MaxPath);
END.
// DevC++: Loco.cpp, Phuong an Cai tien 3
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L
const char * fn = "loco.inp";
const char * gn = "loco.out";
const int mn = 10001;
int s[mn], d[mn];
int n;
int maxv; // Gia tri max trong input file
// P R O T O T Y P E S
void Doc();
int Max(int, int, int);
int MaxPath();
void Tinhd(int);
void Ghi(int);
// I M P L E M E N T A T I O N
int main(){
Doc();
Ghi(MaxPath());
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void Ghi(int m) T vit
int Max(int a, int b, int c) T vit
int MaxPath(){
int k, dmax = 0;
memset(d,0,sizeof(d));
for (k = 1; k <= maxv; ++k)
if (s[k] > 0){
Tinhd(k);

if (dmax < d[k]) dmax = d[k];


}
return dmax;
}
void Tinhd(int k){
int i, k2 = (k-1)/2;
d[k] = 1;
for (i = 1; i <= k2 ; ++i)
if (s[i] > 0 && s[k-i] > 0)
d[k] = Max(d[k],d[i]+1,d[k-i]+1);
k2 = k/2;
if ((2*k2 == k) && (s[k2] > 1))
d[k] = Max(d[k],d[k2]+1,d[k2]+1);
}
void Doc(){
ifstream f(fn);
f >> n;
memset(s,0,sizeof(s));
int i, j;
for (i=1; i <= n; ++i){
f >> j;
if (maxv < j) maxv = j;
if (s[j] > 0) s[j] = 2; else s[j] = 1;
}
f.close();
}

5.6 Chuyn tin


Bch khoa Nng, 2001
Cn chuyn ht n gi tin trn mt mng c m knh truyn. Bit chi ph chuyn i gi tin trn knh j l
C(i,j). Cho bit mt phng n chuyn vi chi ph thp nht.
D liu vo: file vn bn messages.inp:
Dng u tin: 2 s n v m;
Dng th i trong s n dng tip theo: Dy m s nguyn dng b 1, b2, ..., bm trong bj l chi ph
chuyn i gi tin trn knh j.
D liu ra: file vn bn messages.out:
Dng u tin: tng chi ph thp nht theo phng n tm c;
Dng th j trong s m dng tip theo: s lng gi tin chuyn trn knh j.
messages.inp
5 4
31 10 1 1
1 31 12 13
4 10 31 1
6
1 20 19
10 5 10 10

messages.out
2
0
4
1
0

ngha
Vi n = 5 gi tin, m = 4 knh v chi ph c(i,j) cho trc,
trong i l ch s dng (s gi tin), j l ch s ct (knh)
th cch chuyn sau y s cho chi ph thp nht l 2
Knh S gi tin Chi ph
1
0
0
2
4
1
3
1
1
4
0
0

Thut ton Quy hoch ng


Gi s(i,j) l chi ph thp nht ca phng n chuyn ht i gi tin trn mng gm j knh u tin 1, 2, ..., j.
Ta xt knh th j v th chuyn ln lt k = 0, 1, ..., i gi tin theo knh ny. Ta thy, nu chuyn k gi tin
theo knh j th chi ph cho knh j ny s l c(k,j), cn li ik gi tin phi chuyn trn j1 knh u tin vi
chi ph l s(ik,j1), vy phng n ny cho chi ph l c(k,j) + s(ik,j1), k = 0, 1, 2,...,i.
Ta c
s(i,j) = max { c(k,j) + s(ik,j1) | k = 0, 1, ..., i }
ci t, ta c th c th dng 1 mng 1 chiu p vi m bc lp. Ti bc lp th j ta c p[i] = s(i,j) l
chi ph thp nht khi chuyn ht i gi tin trn mng vi j knh u tin. Vy

p[i] = max { c(k,j) + p[ik] | k = i, i1,...,0 }; i = n..1


Ch rng khi ghi ln gi tr cn phi dng x l bc sau, vi mi knh j ta cn duyt i theo
chiu ngc t n n 1.
im kh l phi gii trnh c th phng n chuyn tin ti u, ngha l cho bit phi chuyn theo mi
knh bao nhiu gi tin. Ta s s dng mt mng 2 chiu SoGoi, trong phn t SoGoi[i][j] cho bit trong
phng n ti u chuyn i gi tin theo j knh u tin th ring knh j s c phn phi bao nhiu gi tin.
Trc khi ghi kt qu ta tnh ngc t knh m n knh 1 s gi tin cn chuyn theo mi knh.
phc tp
Th tc XuLi tnh m.n ln, mi ln li tnh ti a m phn t, vy phc tp l O(nm 2).
Chng trnh
(* messages.pas *)
const fn = 'messages.inp'; gn = 'messages.out';
mn = 101; bl = #32; nl = #13#10;
type mi1 = array[0..mn] of integer;
mi2 = array[0..mn] of mi1;
var f,g: text;
c,sogoi: mi2; { c - ma tran chi phi }
{ sogoi[i,j] - so goi tin chuyen theo kenh j }
p: mi1;
n,m: integer; { n - tong so goi tin; m - so kenh }
procedure Ghi;
var i,j: integer;
begin
assign(g,gn); rewrite(g); writeln(g,p[n]);
i := n;
for j := m downto 1 do
begin
p[j] := SoGoi[i,j]; { so goi chuyen theo kenh j }
i := i - SoGoi[i,j]; { so goi con lai }
end;
for i := 1 to m do writeln(g,p[i]);
close(g);
end;
{ Chi phi chuyen het i goi tin
theo j kenh dau tien: 1, 2, ... j }
procedure Tinhp(i,j: integer);
var k: integer;
begin
SoGoi[i,j] := 0;
for k := 1 to i do { thu chuyen k goi theo kenh j }
if (p[i] > p[i-k] + c[k][j]) then
begin
p[i] := p[i-k] + c[k][j]; { cap nhat tri min }
SoGoi[i,j] := k; { chuyen k goi theo kenh j }
end;
end;
procedure XuLi;
var i, j, k: integer;
begin
fillchar(SoGoi,sizeof(SoGoi),0);
{ Khoi tri cho kenh 1 }
{ i goi tin chi chuyen tren kenh 1 voi chi phi c[i][1] }
for i := 1 to n do
begin p[i] := c[i,1]; SoGoi[i,1] := i; end;
for j := 2 to m-1 do { xet kenh j }
for i := n downto 1 do
Tinhp(i,j); { chi phi chuyen i goi tin theo j kenh dau tien }
{ Xu li buoc cuoi, kenh m }
SoGoi[n,m] := 0;
for k := 1 to n do

if (p[n] > p[n-k] + c[k][m]) then


begin
SoGoi[n,m] := k;
p[n] := p[n-k] + c[k][m];
end;
end;
procedure Print;
var i,j: integer;
begin
writeln(nl, n, bl, m);
for i := 1 to n do
begin writeln;
for j := 1 to m do write(c[i,j],bl);
end;
end;
procedure Doc;
var i,j: integer;
begin
assign(f,fn); reset(f);
readln(f, n, m);
for i := 1 to n do
for j := 1 to m do
read(f,c[i,j]);
close(f);
end;
BEGIN
Doc; Print;
XuLi; Ghi;
writeln(nl,' Fini ');
readln;
END.
// DevC++ messages.cpp
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
using namespace std;
// D A T A A N D V A R I A B L E
const char * fn = "messages.inp";
const char * gn = "messages.out";
const int mn = 101;
int c[mn][mn]; // ma tran chi phi
int SoGoi[mn][mn];//SoGoi[i][j]-so goi tin chuyen theo kenh j
int n, m;
int p[mn];
// P R O T O T Y P E S
void Doc();
void Print();
void XuLi();
void Tinhp(int, int);
void Ghi();
// I M P L E M E N T A T I O N
int main() {
Doc(); Print();
XuLi(); Ghi();
cout << endl; system("PAUSE");
return EXIT_SUCCESS;
}
void Ghi(){
ofstream g(gn);
g << p[n]; // chi phi min
int i = n, j;

for (j = m; j > 0; --j) {


p[j] = SoGoi[i][j];
i = i - SoGoi[i][j];// so goi con lai
}
for (i = 1; i <= m; ++i) g << endl << p[i];
g.close();
}
// Chi phi chuyen het i goi tin
// theo j kenh dau tien: 1, 2, ... j
void Tinhp(int i, int j) {
int k;
SoGoi[i][j] = 0;
for (k = 1; k <= i; ++k) // thu chuyen k goi theo kenh j
if (p[i] > p[i-k] + c[k][j]) {
p[i] = p[i-k] + c[k][j]; // cap nhat tri min
SoGoi[i][j] = k; // so goi can chuyen theo kenh j
}
}
void XuLi(){
int i, j, k;
memset(SoGoi, 0,sizeof(SoGoi));
// Khoi tri cho kenh 1
// i goi tin chi chuyen tren kenh 1 voi chi phi c[i][1]
p[0] = 0; // chuyen 0 goi tin tren kenh 1
for (i = 1; i <= n; ++i) {
p[i] = c[i][1]; SoGoi[i][1] = i;
}
for (j = 2; j < m; ++j) // xet kenh j = 2..m-1
for (i = n; i > 0; --i) // chuyen i goi tin tren kenh j
Tinhp(i,j);
// Xu li buoc cuoi, kenh m
SoGoi[n][m] = 0;
for (k = 1; k <= n; ++k) // thu chuyen k goi theo kenh m
if (p[n] > p[n-k] + c[k][m]) {
p[n] = p[n-k] + c[k][m];
SoGoi[n][m] = k;
}
}
void Print(){
int i,j;
cout << endl << n << " goi tin, " << m << " kenh";
for (i = 1; i <= n; ++i) {
cout << endl;
for (j = 1; j <= m; ++j)
cout << " " << c[i][j];
}
}
void Doc(){
ifstream f(fn);
memset(c,0,sizeof(c));
f >> n >> m; // n goi tin, m kenh
int i,j;
for (i = 1; i <= n; ++i)
for (j = 1; j <= m; ++j)
f >> c[i][j];
f.close();
}

5.7 M BW
Olimpic Quc t (Bi d tuyn)
M BW do Michael Burrows and David Wheeler xut dng m ha xu k t s thnh cp (u,d) nh
sau.

1. Quay xu s qua tri mi ln 1 v tr thu c n xu tnh c bn thn xu s,


2. Sp tng cc xu thu c theo trt t t in,
3. Ly cc k cui ca cc xu c sp ghp thnh t u,
4. Xc nh d l v tr xut hin ca xu s trong dy c sp.
Th d, vi s = "panama" ta c kt qu ti cc bc nh sau:
1. Sinh cc xu theo cch quay: "panama", "anamap", "namapa", "amapan", "mapana", "apanam".
2. Sp cc xu: "amapan", "anamap", "apanam", "mapana", "namapa","panama".
3. u = "npmaaa",
4. d = 6.
Kt qu: "panama" c m BW thnh: ("npmaaa", 6).
Cho s, hy tnh (u,d) v bit (u,d), hy xc nh s. Chiu di ti a ca s l 200.
Thut ton
Ta gi BW l thut ton m ha v WB l thut ton gii m. Nh vy, vi th d cho ta c,
BW("panama") = ("npmaaa",6) v WB("npmaaa",6) = "panama".
Bi ton xui BW ch c mt im kh l sinh ra n xu, tnh c xu ngun v sp tng cc xu . Vi xu
ngun s c chiu di ti a l 200 th s i hi min nh 40000 byte c th lu tr cc xu. Ta s trin
khai thut ton vi ch 1 xu ngun s duy nht. Gi s chiu di ca xu s l n. Vi mi i = 1..n ta k hiu
[i] l "xu vng" bt u tnh t k t s[i] n ht xu, tc l n k t s[n] ri li tnh tip n s[1] v kt
thc ti s[i1]. Tm li, xu vng [i] l xu sinh ra khi ta duyt xu ngun s theo vng trn k t v tr i qua
phi. Mi xu di n s c ng n xu vng v mi xu vng c ng n k t. Th d, vi s[1..6] = "panama"
th [2] = "anamap" l mt xu vng. Ta d dng sp xp cc xu vng v ghi nhn trt t trong mt mng
ch dn id. Vi xu cho, sau khi sp tng theo ch dn ta thu c:
id[1] = 4 xu vng [4] = "amapan" ng u tin trong dy sp tng,
id[2] = 2 xu vng [2] = "anamap" ng th hai trong dy sp tng,
id[3] = 6 xu vng [6] = "apanam" ng th ba trong dy sp tng,
id[4] = 5 xu vng [5] = "mapana" ng th t trong dy sp tng.
id[5] = 3 xu vng [3] = "namapa" ng th nm trong dy sp tng.
id[6] = 1 xu vng [1] = "panama" ng cui cng, th su, trong dy sp tng.
D thy, nu [i] l xu vng th k t cui ca xu ny s l k t st tri k t th i trong s, c th l
s[(i+(n1)) % n] nu s biu din trong C++ vi ch s tnh t 0 v l s[(i1+(n1)) mod n + 1] nu s biu
din trong Pascal vi ch s tnh t 1.
Khi sp xp ta gi hm Sanh(s,i,j) so snh hai xu vng [i] v [j] ca s. Hm cho ra gi tr 0 nu hai xu
bng nhau, v 1 nu xu vng [i] ln hn xu vng [j], 1 nu xu vng [i] nh thua xu vng [j].
Hot ng ca hm Sanh 2 xu vng [i] v [j]
1. Duyt n ln cc phn t s[i] v s[j] theo vng trn.
Xt:
- Nu s[i] > s[j]: return 1;
- Nu s[i] < s[j]: return -1;
2. return 0;
3. end.

Bi ton ngc, WB khi phc xu ngun s t xu m u v gi tr d c trin khai nh sau. Trc ht ta


rng xu u l mt hon v ca cc k t trong xu s. Cng do cc xu vng c sp tng nn sau khi
gi hm BS sp tng xu u theo ch dn id ta d dng tnh c xu s nh sau. Ta coi u nh l ct cha
cc k t cui cng ca cc xu vng trong dy c sp v u' l xu sp tng ca xu u. Do dy cc xu
vng c sp tng nn ct u tin ca dy cc xu ny cng phi c sp tng. Vy ct chnh l u'.
Xt k t u[i]. y l k t cui ca mt xu vng v no trong dy c sp. Vy trc khi quay, xu v
s nhn u[i] lm k t u tin, ngha l k t u[i] s thuc v l k t j no trong xu c sp u', ta c
u[i] = u'[j], hay l i c t tng ng vi j. Nh tng ng ny ta c th khi phc xu s K t ny thuc
c xu u'. Nu k t cui trong dy ny l u[j] thi trc khi quay tri mt v tr, k t u[j] phi nm trong
ct u tin c sp.
(* Pascal *)
procedure WB(var u: string; d: integer; var s: string);
var i: integer;
begin

n := length(u);
BS(u); { sp tng xu u theo ch dn }
s := ''; d := id[d];
for i := 1 to n do
begin
s := s + u[d]; d := id[d];
end;
end;
// DevC++
void WB(char *u, int d, char * s) { // (u,d) ==> v
n = int(strlen(u));
BS(u); // sp tng xu u theo ch dn
int i;
d = id[d-1];
for (i = 0; i < n; ++i) {
s[i] = u[d]; d = id[d];
}
s[n] = '\0';
}
Bn phi chn phng thc sp xp khng xo trn cc phn t bng nhau m ch tnh tin cc phn t .
Cc phng php sp xp nh quick sort, min sort u vi phm tiu ch ny. Chng trnh di y s
dng phng php sp ni bt (bubble sort).
(* BW.PAS *)
uses crt;
const bl = #32; nl = #13#10;
var
n: integer;
id: array[0..256] of integer;
procedure iswap(i, j: integer);
var t: integer;
begin
t := id[i]; id[i] := id[j]; id[j] := t;
end;
function Sanh(var s: string; i,j: integer): integer;
var k: integer;
begin
for k := 1 to n do
begin
if s[i] <> s[j] then
begin
if s[i] < s[j] then Sanh := -1 else Sanh := 1;
exit;
end;
i := (i mod n) + 1;
j := (j mod n) + 1;
end;
Sanh := 0;
end;
// sap tang cac xau vong cua s theo chi dan
procedure BubbleSort(var s: string);
var i,j: integer;
begin
for i := 1 to n do id[i] := i;
for i := 1 to n-1 do
for j := n downto i+1 do
if Sanh(s,id[j],id[j-1]) < 0 then iswap(j,j-1);
end;
procedure BW(var s: string; var u: string; var d: integer);
var i: integer;
begin
n := length(s);

BubbleSort(s);
u := '';
for i := 1 to n do
begin
u := u + s[(id[i]-1+n-1) mod n + 1];
if id[i] = 1 then d := i;
end;
end;
procedure BS(var u: string);
var i,j: integer;
begin
for i := 1 to n do id[i] := i;
for i := 1 to n-1 do
for j := n downto i+1 do
if u[id[j]] < u[id[j-1]] then iswap(j,j-1);
end;
procedure WB(var u: string; d: integer; var s: string);
var i: integer;
begin
n := length(u);
BS(u);
s := ''; d := id[d];
for i := 1 to n do
begin
s := s + u[d]; d := id[d];
end;
end;
procedure Test;
var s, u, v: string;
d: integer;
begin
s := 'panama';
BW(s,u,d);
writeln(s,' => (',u,',',d,')');
WB(u,d,v);
writeln('(',u,',',d,') => ',v);
end;
BEGIN
Test;
readln;
END.
// DevC++: Bw.cpp
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L E
const char * fn = "bw.inp";
const char * gn = "bw.out";
const int mn = 256;
char s[mn];
char u[mn];
char v[mn];
int id[mn];
int n,d; // n = len(s); d: vi tri cua s trong day duoc sap
// P R O T O T Y P E S
// BW(s) = (u,d)
// WB(u,d) = v ( = x)
void BW(char * s, char * u, int & d);
void WB(char * u, int d, char * s);
int Sanh(char * s, int i, int j);
void BubbleSort(char * s);
void BS(char * u); // BubbleSort tren u
void iswap(int i , int j ); // doi cho id[i], id[j]

// I M P L E M E N T A T I O N
int main() {
strcpy(s,"panama");
BW(s,u,d);
cout << endl << "BW(" << s << ") = (" << u
<< ", " << d << ")" << endl;
WB(u,d,v);
cout << endl << "WB(" << u << ", " << d << ") = " << v;
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void BW(char * s, char * u, int & d) { // s ==> (u,d)
n = int(strlen(s));
BubbleSort(s);
for (int i = 0; i < n; ++i) {
u[i] = s[(id[i] + n - 1) % n];
if (id[i] == 0) d = i+1;
}
u[n] = '\0';
}
void BubbleSort(char * s){
// sap tang cac xau vong cua s theo chi dan
int i,j, n1 = n - 1;
for (i = 0; i < n; ++i) id[i] = i;
for (i = 0; i < n1; ++i) {
for (j = n1; j > i; --j)
if (Sanh(s,id[j],id[j-1]) < 0) iswap(j,j-1);
}
}
int Sanh(char * s, int i, int j) { // sanh 2 xau vong [i] va [j]
int k;
for (k = 0; k < n; ++k, i = (i+1)%n, j = (j+1)%n)
if (s[i] != s[j]) return (s[i] > s[j]) ? 1 : -1;
return 0;
}
void iswap(int i, int j) { int t = id[i]; id[i]= id[j]; id[j] = t; }
void WB(char *u, int d, char * s) { // (u,d) ==> v
n = int(strlen(u));
BS(u);
int i;
d = id[d-1];
for (i = 0; i < n; ++i) {
s[i] = u[d]; d = id[d];
}
s[n] = '\0';
}
void BS(char *u){ // sap tang xau u theo chi dan
int i,j,n1 = n-1;
for (i = 0; i < n; ++i) id[i] = i;
for (i = 0; i < n1 ; ++i) {
for (j = n1; j > i; --j)
if (u[id[j]] < u[id[j-1]]) iswap(j,j-1);
}
}

5.8 Tam gic Pascal

Tam gic Pascal bc n l mt bng gm n dng, dng th i l mt dy gm i+1 s t nhin c xy dng


nh sau.
Dng i = 1 cha hai s 1, 1.
Gi x = (x1, x2, ..., xi+1) l dng th i, th dng th i+1, y = (y1, y2, ..., yi+2) c xy dng nh sau:
y1 = yi+2 = 1,
yj = xj-1+xj , j = 2, 3, ..., i+1.
Cc phn t ca dy c gi l h s. Hai phn t u v cui ca mi dy lun lun mang gi tr 1 v
c gi l hai h s ngoi. Cc phn t cn li c gi l cc h s trong.

Blaise Pascal
Nh vt l hc, ton hc v trit gia ngi Php. ng c
tip thu nn gio dc t ngi cha. Ngay t thi tr Pascal
ni ting l thn ng. Cc tc phm u tin ca Pascal l v
t nhin v cc khoa hc ng dng, ni ng c nhng ng
gp quan trng vo vic xy dng mt my tnh c kh, cc
nghin cu v cht lng, trnh by cc khi nim v p sut v
chn khng bng vic khi qut tc phm ca Evangelista
Torricelli.
Pascal l mt trong nhng ngi t nn mng cho hai lnh
vc nghin cu mi ca ton hc. ng vit mt lun n
quan trng v hnh hc x nh tui 16. Cng vi Pierre de
Fermat xy dng l thuyt xc sut. y l cng trnh c nh
hng ln ti s pht trin ca kinh t hc hin i v cc
khoa hc x hi.
Sau ng dnh tm sc vo trit hc v thn hc vi hai tc
phm ni ting trong thi k .
Ngun: Wikipedia

Blaise Pascal
19/6/1623-19/8/1662

Tam gic Pascal (PT Pascal's Triangle ) c nhiu ng dng ni ting. Dng th n trong PT chnh l cc
h s trong dng khai trin ca a thc (a+b)n. nh l sau y cho ta mt du hiu nhn bit s nguyn
t da trn PT.
nh l: n l s nguyn t khi v ch khi mi h s trong ca dng n trong tam gic Pascal chia ht cho n.
Chng ta th gii hai bi ton sau y lin quan n tam gic Pascal.
PT1: Vi mi s t nhin n hy tnh cc h s ca tam gic Pascal v tng ca chng.
PT2: K hiu a(i,n) l h s th i trn dng th n ca m gic Pascal. Hy tnh tng
(n) = sum { a(i, i/2+1) | i = 1..n } = a(1,1) + a(2,2) + a(3,2)+ ... + a(i, i/2+1) + ... + a(n, n/2+1)
trong d x/y cho ta phn nguyn ca thng trong php chia s t nhin x cho s t nhin y. Gii hn ca
n l 1 n 20.
Th d, vi n = 6 ta c
PT1: Dng 6 ca tam gic Pascal: (1, 6, 15, 20, 15, 1); Tng l: 64.
PT2: (6) = 1 + 2 + 3 + 6 + 10 + 20 = 42 (cc s gch di trong bng).
ng dng

n
1
2
3
4
5
6

Thut ton

1
1
1
1
1
1
.

1
2
3
4
5
6
.

1
3 1
6 4 1
10 10 5 1
15 20 15 6 1
.

Dng 4:
(a+b)4=1a4+4a3b+6a2b2+4ab3+1b4.
Dng 5: Mi h s trong chia ht
cho 5, vy n = 5 nguyn t.
Dng 6: H s 15 khng chia ht
cho 6, vy 6 khng phi nguyn t.

H s th i trn dng n, p(n, i) ca PT chnh l t hp chp i1 ca n phn t do c tnh theo cng


thc:
p(n,i) = Cn i1 = n!/(i1)!(ni+1)! = (ni+2)...n/(i1)!,
i = 1.. n+1.
Ta qui c 0! = 1, do
p(n, 1) = p(n, n+1) = Cn0 = Cnn = 1
Bit p(n, i) ta tnh c p(n, i+1) theo cng thc sau:
p(n, i+1) = p(n, i).(ni+1)/i
(*)
Ta khi tr a[1] = 1 ng vi p(n, 1). Ngoi ra ta s dng hai bin ph tu v mau vi gi tr khi u l tu =
n, mau = 1. Sau , vi mi i = 2..n+1 ta tnh p(n, i) = a[i] = a[i-1]*tu/mau v gim tu, tng mau 1 n v.
Th tc PT di y tnh v hin th dng th n trong tam gic Pascal:
(* Passcal *)
procedure PT(n: integer);
var x: longint;
i, tu, mau: integer;
begin
x := 1; tu := n; mau := 1;
for i := 2 to n+1 do
begin
write(x,bl); { bl l du cch, bl = #32 }
x := (x * tu) div mau;
dec(tu); inc(mau);
end;
write(1);
end;
// DevC++
void PT(int n) {
int x = 1;
int i, n1 = n+1, tu = n, mau = 1;
for (i = 2 ; i <= n1; ++i, --tu, ++mau) {
cout << x << " ";
x = x*tu/mau;
}
cout << 1;
}
tnh tng cc h s trn dng th n ca PT, T(n), ta xt dng khai trin ca a thc (a+b)n:
(a+b)n = p(n, 1)an + p(n, 2)an-1b + ... + p(n, i)an-i+1bi-1 + ... + p(n, n+1)bn
Thay a = b = 1 vo biu thc trn ta thu c:
T(n) = (1+1)n = 2n = p(n, 1) + p(n, 2) + ... + p(n, i) + ... + p(n, n+1)
n
Vy T(n) = 2 . Do cc s nguyn trong my tnh c biu din di dng nh phn nn hm T(n) nhn gi
tr l s 1 dch qua tri n bit:
(* Passcal *)
function T(n: integer): longint;
begin T := longint(1) shl n; end;
// DevCPP
int T(int n) {

return (1 << n); }

tnh hm (n) trc ht ta cn tnh c p(i, j) vi i = 1..n v j = i/2 + 1. Ta gi x l gi tr ca


p(i,i/2+1) tnh c ti bc i. Ta c nhn xt sau y:
Khi i = 1 ta c x = p(1,1) = 1;
Nu i l s chn th gi tr ca x c tng gp i: x = 2 *x.
Nu i l s l th x = x + x', trong x l gi tr tnh c bc st trc, bc i1, x =
p(i1,v), v = (i1)/2; x' l gi tr st sau x ti bc i1, x' = p(i1, v+1). S dng cng thc (*) ta
d dng tnh c x' t x. Khi ci t ta s dng bin v ghi nhn ch s ca h s cn tnh ti
bc i. v c khi tr 1, sau tng thm 1 nu gp dng chn. Ta cng s dng bin bool even
xc nh dng chn.
Th tc Test trong cc chng trnh di y tnh ng thi vi mi gi tr n = 1..20 cc i lng sau y:
Dng th n trong tam gic Pascal v tng cc h s trn dng;
Hm .
kt thc chng trnh bn hy bm du chm (.).
phc tp: O(n) cho c hai th tc PT v Alpha.
Chng trnh
(* Triangle.pas *)
uses crt;
const bl = #32; nl = #13#10;
procedure PT(n: integer);
var x: longint;
i, tu, mau: integer;
begin
x := 1; tu := n; mau := 1;
for i := 2 to n+1 do
begin
write(x,bl);
x := (x * tu) div mau;
dec(tu); inc(mau);
end;
write(1);
end;
function Alpha(n: integer): longint;
var x, sum, i, v: integer;
even: Boolean;
begin
x := 1; sum := 1; even := false; v := 1;
for i := 2 to n do
begin
even := not even;
if (even) then
begin
inc(v); x := x * 2;
end
else x := x + x * (i-v) div v;
sum := sum + x;
end;
Alpha := sum;
end;
procedure Test;
var n: integer;
begin
for n := 1 to 20 do
begin
writeln(nl, ' n = ',n);
write(' a = '); PT(n);
writeln(nl, ' Tong = ', longint(1) shl n);
writeln(' Alpha = ',Alpha(n));
write(nl,' Bam . de ket thuc: ');
if readkey = '.' then exit;
end;

end;
BEGIN
Test;
END.
// DevC++: Triangle.cpp
#include <iostream>
using namespace std;
// P R O T O T Y P E S
void PT(int);
int Alpha(int );
void Test();
// I M P L E M E N T A T I O N
int main() {
Test();
return 0;
}
void Test(){
int n;
for (n = 1; n <= 20; ++n) {
cout << endl << " n = " << n << ":";
cout << endl << "a = "; PT(n);
cout << endl << " Tong = " << (1 << n);
cout << endl << " Alpha = " << Alpha(n) << " ";
cout << endl << endl << " Bam . de ket thuc: ";
if (cin.get() == '.') return;
}
}
// p(i, v+1) = p(i, v).(i-v+1)/v, v = i/2 + 1
int Alpha(int n) {
int sum = 1, x = 1, v = 1, i;
bool even = false;
for (i = 2 ; i <= n; ++i) {
even = !even;
if (even) { // i chan
v++; x *= 2;
} else x += x*(i-v)/v;
sum += x;
}
return sum;
}
void PT(int n) {
int x = 1;
int i, n1 = n+1, tu = n, mau = 1;
for (i = 2 ; i <= n1; ++i, --tu, ++mau) {
cout << x << " ";
x = x*tu/mau;
}
cout << 1;
}

5.9 Sn m hnh
Moscow
Bn Minh lm mt m hnh nh sau: Trn mt tm bng nha hnh ch nht chia li kch thc n m
n v Minh dng keo gn ti mt s ca bng mt ct g vung cnh y 1 n v, chiu cao l mt s
nguyn. Cc ct g k nhau cng c gn keo gia hai mt tip gip. Sau Minh sn cc mt g tip
xc vi khng kh. Tnh din tch cn sn.
son.inp
2 3
1 2 0
5 4 5

son.out
49

Gii thch
file son.inp: dng u tin: 2 s nguyn dng n v m.
Phn t th j trn dng i trong s n dng tip theo l chiu cao ca ct t
ti (i, j).
file son.out: din tch cn sn.

Thut ton
Bi ny kh d nhng hu ht cc bn u qnun sn mt trn. Vi mi ct ta tnh din tch cn sn trn 4
mt ct nu ti mt phn tng cao hn ct bn cnh. Ta vit hm Hieu(x,y) cho ra hiu xy nu x >
y, ngc li hm cho ra gi tr 0. Nh vy hm ny cho ra din tch cn sn trn phn l ca bc tng cao
x v bc tng cao y k n (x > y). Sau , nu no c ct ( cao ln hn 0) bn nh cng thm din
tch sn mi l 1 n v. Khi c d liu vo mng bn nn in cc vin phia ngoi bng gi tr 0.
phc tp: O(n.m) v ta duyt mi 1 ln.
Chng trnh
(* son.pas *)
uses crt;
const mn = 101; bl = #32; nl = #13#10;
fn = 'son.inp'; gn = 'son.out';
var n, m: integer;
a: array[0..mn,0..mn] of integer;
procedure Doc;
var i,j: integer;
f: text;
begin
assign(f,fn); reset(f);
readln(f, n, m);
fillchar(a, sizeof(a), 0);
for i := 1 to n do
for j := 1 to m do
read(f,a[i,j]);
close(f);
end;
procedure Ghi(d: longint);
var g: text;
begin
assign(g,gn); rewrite(g);
writeln(g,d); close(g);
end;
procedure Print;
var i,j: integer;
begin
writeln(nl,n, bl, m);
for i := 1 to n do
begin
for j := 1 to m do write(a[i,j], bl);
writeln;
end;
end;
function Hieu(x, y: integer): integer;
begin
if x > y then Hieu := x - y else Hieu := 0;
end;
function Son: longint;
var d: longint;
i, j: integer;
begin
d := 0;
for i := 1 to n do
for j := 1 to m do
begin
d := d + Hieu(a[i,j], a[i+1,j]) + Hieu(a[i,j], a[i-1,j]) +
Hieu(a[i,j], a[i,j+1]) + Hieu(a[i,j], a[i,j-1]);
if a[i,j] > 0 then inc(d);
end;
Son := d;

end;
BEGIN
Doc; Print; Ghi(Son);
readln;
END.
// DevC++: son.cpp
#include <iostream>
#include <fstream>
using namespace std;
// D A T A
A N D V A R I A B L E S
const char * fn = "son.inp";
const char * gn = "son.out";
const int mn = 102;
int a[mn][mn];
int n,m;
// P R O T O T Y P E S
void Doc();
int Son();
int Hieu(int, int);
void Print(); // xem du lieu
void Ghi(int);
// I M P L E M E N T A T I O N
int main() {
Doc(); Ghi(Son());
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void Print() { // Hin th bng a
int i,j;
cout << endl << " n = " << n << "
m = " << m;
for (i = 0; i <= n+1; ++i) {
cout << endl;
for (j = 0; j <= m+1; ++j)
cout << a[i][j] << " ";
}
}
void Doc() {
memset(a,0,sizeof(a));
ifstream f(fn);
f >> n >> m;
int i,j;
for (i = 1; i <= n; ++i)
for (j = 1; j <= m; ++j)
f >> a[i][j];
f.close();
Print();
}
void Ghi(int d) {
ofstream g(gn);
g << d;
g.close();
}
int Son() {
int i,j, d = 0; // d: dien tich can son
for (i = 1; i <= n; ++i)
for (j = 1; j <= m;++j) {
d += Hieu(a[i][j],a[i][j+1])+Hieu(a[i][j],a[i][j-1])
+ Hieu(a[i][j],a[i-1][j]) + Hieu(a[i][j],a[i+1][j]);
if (a[i][j] > 0) ++d;
}
return d;

}
int Hieu(int x, int y) { return (x > y) ? (x - y) : 0;

5.10 Nhng m hnh


Bn Minh lm mt m hnh nh sau: Trn mt tm bng nha hnh ch nht chia li kch thc n m
n v Minh dng keo gn ti mt s ca bng mt ct nha vung cnh y 1 n v, chiu cao l mt
s nguyn. Cc ct k nhau cng c gn keo gia hai mt v hai cnh tip gip. Sau Minh nhng m
hnh ngp vo nc ri cn thn nhc ln. Tnh th tch ca khi nc ng trong m hnh.
model.inp
4 5
5 5 4 5 5
5 4 0 3 0
5 0 5 2 5
5 5 4 5 5

model.out
8

Gii thch
file model.inp: dng u tin: 2 s nguyn dng n v m.
Phn t th j trn dng i trong s n dng tip theo l chiu cao ca ct t
ti (i, j).
file model.out: th tch nc ng trong m hnh.

Thut ton
Gi a l tm bng nn m hnh vi kch thc nm v a(i,j) l chiu cao ca ct nha vung t trn (i,j).
Thot tin ta gi s chiu cao ti a ca cc ct l 1, nh vy cc trn nn nh ch cha cc gi tr 0 hoc
1.
1

Nn tng 1 vi cc c mang gi tr 1, cha nc ng mu trng


(0) v thot nc mu xm (0).
0
thot nc
C 5 trng b giam nn th tch nc
ng s l 5.
0
nc ng
Cc lin thng vi trng trn bin s
to thnh nt cng thot nc ra ngoi m
1
c
hnh.

mang gi tr 0 chnh l mt sn, cn mang gi tr 1 chnh l ct. By gi bn th rt nc vo m hnh


n gin ny cho ngp cc v quan st iu g s xy ra. D thy l ch c cc trng b giam ti gia m
hnh l cn cha nc. C 5 trng b giam nn th tch nc ng s l 5. Cc trng (mang gi tr 0)
lin thng cnh vi mt trng trn bin s to thnh mt cng thot nc ra ngoi m hnh. Nhn xt ny
cho ta thut ton tnh lng nc ng ti tng nn (tng 0) ca m hnh nh sau:
Dut ng bin, nu gp trng (trn bin v cha tr 0) th gi th tc loang nh du cc ny bng
gi tr 1.
Duyt cc lt trong m hnh, m cc trng (cha gi tr 0) v ng thi nh du cc ny bng gi tr
1. l th tich nc ng.
Tip theo, sau khi duyt v tnh lng nc ng ti tng nn (tng 0), bn d dng suy ra cch tnh
lng nc ng ti tng 1 nu nh coi cc trng duyt ti tng 0 c lp bng cc khi nha
chiu cao 1. Ta gi phng thc ny l ng bng cc x l. Tng qut, ti tng h ta thc hin th tc
tng t nh ti tng nn vi cht iu chnh l thay gi tr nh du bng h+1 thay v bng 1. Gi chiu
cao ti a ca cc ct l hmax, cho h bin thin t 0 n hmax1 ta tnh c tng khi nc ng ca m
hnh.
thc hin thut ton loang bn nh khi tr mi ca nn nh l 1.
Th tc Loang(i,j,h)
1. Xt tr ca (i,j):

Nu a(i,j) = h th
1.1 Thay a(i,j) bng h+1;
1.2 Loang tip sang 4 k: (i,j+1), (i,j-1), (i+1,j) v (i-1,j)
2. end.
phc tp
Mi tng ta duyt n.m vy tng s phi duyt vo c hmax.n.m.
Chng trnh
(* Model.Pas *)
uses crt;
const mn = 101; bl = #32; nl = #13#10;
fn = 'model.inp'; gn ='model.out';
var
n, m: integer;
a: array[0..mn, 0..mn] of integer;
hmax: integer;
procedure Doc;
var f: text;
i,j: integer;
begin
assign(f,fn); reset(f);
fillchar(a,sizeof(a),255); // gan -1
readln(f,n,m); hmax := 0;
for i := 1 to n do
for j := 1 to m do
begin
read(f,a[i,j]);
if hmax < a[i,j] then hmax := a[i,j];
end;
close(f);
end;
procedure Ghi(v: integer);
var g: text;
begin
assign(g,gn); rewrite(g);
writeln(g,v); close(g);
end;
procedure Loang(i,j,h: integer);
begin
if a[i,j] <> h then exit;
a[i,j] := h+1;
Loang(i+1,j,h); Loang(i-1,j,h);
Loang(i,j+1,h); Loang(i,j-1,h);
end;
function Tang(h: integer): longint;
var i, j: integer;
v: longint;
begin
for i := 1 to n do { canh trai, phai }
begin
Loang(i,1,h); Loang(i,m,h);
end;
for j := 2 to m-1 do { canh tren, duoi }
begin
Loang(1,j,h); Loang(n,j,h);
end;
v := 0; { Duyet trong }
for i := 2 to n-1 do

for j := 2 to m-1 do
if a[i,j] = h then
begin
inc(v);
a[i,j] := h+1;
end;
Tang := v;
end;
function TheTich: longint;
var h: integer;
v: longint;
begin
v := 0;
for h := 0 to hmax-1 do v := v + Tang(h);
TheTich := v;
end;
BEGIN
Doc; Ghi(TheTich);
readln;
END.
// DevC++: Model.cpp
#include <iostream>
#include <fstream>
using namespace std;
// D A T A
A N D V A R I A B L E S
const char * fn = "model.inp";
const char * gn = "model.out";
const int mn= 102;
int a[mn][mn];
int n,m;
int hmax;
// P R O T O T Y P E S
void Doc();
void Ghi(int);
int TheTich();
int Tang(int);
void Loang(int, int, int);
// I M P L E M E N T A T I O N
int main(){
Doc(); Ghi(TheTich());
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void Doc(){
memset(a,0xff,sizeof(a));
ifstream f(fn);
f >> n >> m; hmax = 0;
int i,j;
for (i = 1; i <= n; ++i)
for (j = 1; j <= m; ++j){
f >> a[i][j];
if (a[i][j] > hmax) hmax = a[i][j];
}
f.close();
}
void Ghi(int v) {
ofstream g(gn);
g << v;
g.close();
}
void Loang(int i, int j, int h){

if (a[i][j] != h) return;
++a[i][j];
Loang(i,j+1,h);
Loang(i,j-1,h);
Loang(i+1,j,h);
Loang(i-1,j,h);
}
int Tang(int h){ // The tich nuoc bi giam tai tang h
// Loang ngoai
int i,j;
for (i = 1; i <= n; ++i){
Loang(i,1,h); // bien trai
Loang(i,m,h); // bien phai
}
for (j = 2; j < m; ++j){
Loang(1,j,h); // bien tren
Loang(n,j,h); // bien duoi
}
// Tong khoi nuoc bi giam ben trong
int v = 0;
for (i = 2; i < n; ++i)
for (j = 2; j < m; ++j)
if (a[i][j] == h) {
v++; ++a[i][j];
}
return v;
}
int TheTich(){
int h, v = 0; // v: The tich nuoc bi giam
for (h = 0; h < hmax; ++h)
v += Tang(h);
return v;
} // end

5.11 S st sau nh phn


Cho s t nhin x trong dng thp phn c ti a 200 ch s. Tm s t nhin y u tin ln hn x v
dng nh phn x v y c cng s ch s 1.
D liu vo: file vn bn binnext.inp:
Dng u tin: N s ch s ca x
Dng th hai: s x dng thp phn vi cc ch s vit lin nhau.
D liu ra: file vn bn binnext.out:
Dng u tin: M s ch s ca y
Dng th hai: s y dng thp phn vi cc ch s vit lin nhau.
binnext.inp

binnext.out

Gii thch

2
22

2
25

Trong dng nh phn s 22 c dng 10110 v cha 3 bit 1. Cc s


23, 24 v 25 c dng nh phn ln lt l 10111, 11000, 11001. Vy
25 l s st sau s 22 cha ng 3 bit 1 trong dng nh phn.

Thut ton
Trc ht ta phc tho khung bi gii di dng
Thut ton BinNext
1. c s x t input file;
2. ToBin(x,y): Chuyn s x sang dng nh phn v ghi vo
bin y;
3. Next(y): Tm s nh phn st sau s y v c cng s bit

1 vi y; Kt qu ghi ngay trong y;


4. ToDec(y,z): Chuyn s nh phn y sang dng thp
phn; Kt qu ghi trong z;
5. Ghi s z vo output file;
6. end.

Thut ton ToBin(x , y)


i := 0;
repeat
t bit y[i] := x%2;
i := i + 1;
x := x / 2;
until x = 0;
return y;

chuyn mt s x sang dng biu din nh phn y


ta chia lin tip x cho 2 v ghi cc s d theo trt
t ngc tc l t bit thp n bit cao.

Thut ton ToDec(y , x)


x := 0;
Duyt (cc bit y[i] t cao n
thp)
x := x*2 + y[i];
return x;

chuyn mt s nh phn y sang dng


biu din thp phn x ta s dng thut
ton Horne duyt ngc cc bit t cao
n thp: nhn lin tip x vi 2, cng
thm bit va duyt.

V x l s ln nn ta cn biu din chng di dng mng. Ta s dng mng nguyn x[0..n] biu din
mt s (nh phn hay thp phn) chiu di n, trong phn t x[0] c dng lu chiu di n, tc l ta
t x[0] := n. Ta bit, trong h m a, s x c loga(x)+1 ch s do khi chuyn i x sang h m b s
c logb(x) + 1 ch s. Theo nh ngha ca logarit ta c logb(x) = loga(x).logb(a). Vi a = 10, b = 2 ta c:
log2(x) = log2(10).log10(x) 4.log10(x)
Nh vy, vi s thp phn x c ti a 200 ch s th khi chuyn i x qua dng nh phn s c ti a 800
ch s.
rng, khi lm cc php ton s hc, cc kt qu c th ln dn, tc l s ch s ca kt qu pht trin
dn v bn tri (hng cao), do ta nn lu cc ch s ca chng theo chiu ngc, t hng n v tr i.
Th d, s 157 s c biu din trong mng x nh sau: x[0..3] = (3,7,5,1), trong x[0] = 3 l s ch s
ca x. Vi cch biu din ny, khi s ch s tng ln th chng s c b sung vo bn phi mng, do
ta khng phi dch chuyn cc ch s.
Di y s gii trnh mt s th tc.
Div2(x): Thc hin php chia nguyn s x cho 2, x := x / 2. chia nguyn mt s ln x cho 2 ta chia
nguyn ln lt tng ch s ca x cho 2, tnh t ch s hng n. Nu gp ch s l th ta cng thm 5 vo
ch s kt qu thu c ti bc trc . Cui cng ta b bt cc ch s 0 hng cao. Th d, thc
hin php chia nguyn s x = 157 cho 2 ta lu rng x c biu din ngc nh sau x[0..3] = (3, 7, 5, 1).
Khi
Xt x[1] = 7: x[1] := x[1] / 2 = 7 / 2 = 3;
Xt x[2] = 5:
V x[2] = 5 l s l nn ta chnh li x[1] := x[1] + 5 = 3 + 5 = 8;
x[2] := x[2] / 2 = 5 / 2 = 2;
Xt x[3] = 1:
V x[3] = 1 l s l nn ta chnh li x[2] := x[2] + 5 = 2 + 5 = 7;
x[3] := x[3] / 2 = 1 / 2 = 0.
Ta thu c x[0..3] = (3, 8, 7, 0). Sau khi b s 0 u phi (hng cao) ta thu c x[0..2] = (2, 8, 7). iu
ny c ngha 157 / 2 = 78.
Next(x) Xc nh s nh phn st sau x v c cng s bit 1 nh x, kt qu ghi ti x. Tnh hung ny
c gi l x l ti ch. Trng hp duy nht v nghim l khi x = 0. Th tc ny thc hin nh sau:

Hm Next(x): Sa s nh phn x thnh s nh phn st sau x v c cng s bit 1 nh x

1. Nu x = 0: Gi kt qu v nghim; That khi th tc;


2. Duyt x t bit thp (i = 1) tr i, tm bit i u tin nhn gi tr 1, x[i] = 1.
3. Duyt tip t i+1 tm bt j u tin nhn gi tr 0, x[j] = 0;
4. Lt hai bit i v j: x[i] = 0; x[j] = 1;
5. o li on x[1..j1].
6. end.

Th d, vi x = 100110 ta c dng biu din ngc ca x l x[0..6] = (6,0,1,1,0,0,1). Ta c:


i = 2, x[i] = x[2] = 1;
j = 4, x[j] = x[4] = 0;
t li x[2] = 0; x[4] = 1 ta thu c x[0..6] = (6,0,0,1,1,0,1);
Lt on x[1..3] ta thu c x[0..6] = (6,1,0,0,1,0,1).
Vy 101001 l s st sau s x = 100110 v c cng 3 bt 1 nh x.
MultPlus(x,c) Thc hin vic tnh x = 2*x + c. Th tc ny dng trong thut ton ToDec(x,y)
chuyn i s nh phn x sang dng thp phn y. Th tc hot ng nh sau: duyt cc ch s ca x t
hng n tr i. Vi mi ch s x[i] ta tnh x[i] := (2*x[i] + c) mod 10. Ta coi c nh l s nh ca php
nhn, do ta cn tnh li c = (2*x[i] + c) div 10.
Nh th tc ny, khi c = 0 ta tnh c ngay th tc x = x*2 vi li gi MultPlus(x,0).
bool IsZero(char * x): Kim tra s ln x = 0?
bool Odd(char c): Kim tra s ln x l s l?
(* Binnext.pas *)
uses crt;
const fn = 'binnext.inp'; gn = 'binnext.out';
mn = 801; bl = #32; nl = #13#10;
type mi1 = array[0..mn] of integer;
var x,y: mi1;
n: integer;
(* Ghi file *)
procedure Save(var x: mi1; fn: string);
var g: text; i: integer;
begin
assign(g,gn); rewrite(g);
writeln(g,x[0]); { x[0] chiu di s x }
for i := x[0] downto 1 do write(g,x[i]); { Ghi ngc }
close(g);
end;
function IsZero(var x: mi1): Boolean;
begin IsZero := (x[0] = 1) and (x[1] = 0) end;
{ so nhi phan sat sau x }
function Next(var x: mi1): Boolean;
var i, j, k: integer;
begin
Next := false;
if (IsZero(x)) then exit;
{ tim so 1 dau tien }
i := 1;
while x[i] = 0 do inc(i);
{ x[i] = 1 }
{ tim so 0 dau tien sau i }
j := i+1;
while x[j] = 1 do inc(j);
if (j > x[0]) then
begin
inc(x[0]); { them 1 vi tri }
j := x[0];
end;
x[i] := 0; x[j] := 1;

i := 1; j := j-1;
while (i < j) do
begin
k := x[i]; x[i] := x[j]; x[j] := k;
inc(i); dec(j);
end;
Next := true;
end;
procedure MultPlus(var x: mi1; c: integer); { x := 2*x + c }
var i: integer;
begin
for i := 1 to x[0] do
begin
c := 2*x[i] + c; { c la so nho }
x[i] := c mod 10;
c := c div 10;
end;
if (c > 0) then begin inc(x[0]); x[x[0]] := c; end;
end;
procedure ToDec(var x,y: mi1);
var i: integer;
begin
y[0] := 1; y[1] := 0; { Khoi tri y = 0 }
for i := x[0] downto 1 do
MultPlus(y,x[i]);
end;
procedure Div2(var x: mi1); { x := x div 2 }
var i: integer;
begin
x[1] := x[1] div 2;
for i := 2 to x[0] do
begin
if Odd(x[i]) then inc(x[i-1],5);
x[i] := x[i] div 2;
end;
i := x[0];
while (x[i] = 0) do dec(i);
if i = 0 then i := 1;
x[0] := i;
end;
procedure ToBin(var x,y: mi1);
var i: integer;
begin
i := 0;
repeat
inc(i);
if Odd(x[1]) then y[i] := 1 else y[i] := 0;
Div2(x);
until IsZero(x);
y[0] := i;
end;
procedure Init(var x: mi1; fileName: string);
var i: integer; c: char; f: text;
begin
fillchar(x,sizeof(x),0);
assign(f,fn); reset(f);
readln(f,x[0]);
writeln(x[0]);
for i := x[0] downto 1 do
begin
read(f,c); x[i] := ord(c)-ord('0');
write(x[i]);
end;

close(f);
end;
procedure Print(var x: mi1);
var i: integer;
begin
for i := x[0] downto 1 do write(x[i]);
end;
procedure Run;
begin
Init(x,fn); { Doc so x tu file fn }
write(nl, ' x = '); Print(x);
ToBin(x,y); { Chuyen x sang dang nhi phan y }
write(nl, ' y = '); Print(y);
if (Next(y)) then
begin { So nhi phan sat sau y }
write(nl, ' y = '); Print(y);
ToDec(y,x); { Doi y sang x }
write(nl, ' x = '); Print(x);
end else { x = 0: vo nghiem }
begin x[0] := 1; x[1] := 0; end;
Save(x,gn);
end;
BEGIN
Run;
writeln(nl,' Fini '); readln;
END.

// DevC++: binnext.cpp
#include <string.h>
#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 = "binnext.inp";
const char * gn = "binnext.out";
const int mn = 1001;
int x[mn], y[mn];
int n;
// P R O T O T Y P E S
void Init(int *, const char *);
void Save(int *, const char *);
void Print(int *);
bool Odd(int);
bool Even(int);
bool Odd(int *);
bool Even(int *);
void MultPlus(int *, int);
void Div2(int *);
void ToBin(int *, int *);
bool IsZero(int *);
void ToDec(int *, int *);
bool Next(int * x);
void Run();
// 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 Run() {

Init(x,fn); // Doc so x tu file fn


cout << endl << " x = "; Print(x);
ToBin(x,y); // Chuyen x sang dang nhi phan y
cout << endl << " y = "; Print(y);
if (Next(y)) { // So nhi phan sat sau y
cout << endl << " y = "; Print(y);
ToDec(y,x); // Doi y sang x
cout << endl << " x = "; Print(x);
}
else { // vo nghiem: 0
x[0] = 1; x[1] = 0;
}
Save(x,gn);
}
// Ghi file
void Save(int * x, const char * fileName) {
ofstream g(gn);
g << x[0] << endl;
for (int i = x[0]; i > 0; --i) g<< x[i];
g.close();
}
// so nhi phan sat sau x
bool Next(int *x) {
int i, j, k;
if (IsZero(x)) return false;
// tim so 1 dau tien
for (i = 1; i <= x[0]; ++i)
if (x[i] == 1) break;
// tim so 0 dau tien sau i
for (j = i+1; j <= x[0]; ++j)
if (x[j]==0) break;
if (j > x[0]) ++x[0]; // them 1 chu so
x[i] = 0; x[j] = 1;
i = 1; --j;
while (i < j) {
k = x[i]; x[i] = x[j]; x[j] = k;
++i;--j;
}
return true;
}
bool IsZero(int * x) { return (x[0]==1 && x[1]==0); }
void ToDec(int *x, int *y){
int i;
y[0] = 1; y[1] = 0;
for (i = x[0]; i > 0; --i)
MultPlus(y,x[i]);
}
void ToBin(int * x, int *y) {
int i = 0;
do {
y[++i] = Odd(x);
Div2(x);
} while (! IsZero(x));
y[0] = i;
}
void Div2(int * x) {
int i;
x[1] /= 2;
for (i = 2; i <= x[0]; ++i) {
if (Odd(x[i])) x[i-1] += 5;
x[i] /= 2;
}
i = x[0];

while (x[i] == 0 && i > 1) --i;


x[0] = i;
}
// x = x*2 + c
void MultPlus(int * x, int c) {
int i;
for (i = 1; i <= x[0]; ++i) {
c = 2*x[i] + c; // c la so nho
x[i] = c % 10;
c /= 10;
}
if (c > 0) { ++x[0]; x[x[0]] = c; }
}
bool Odd(int c) { return (c%2) == 1; }
bool Even(int c) { return !Odd(c); }
bool Odd(int * x) { return (x[1]%2) == 1; }
bool Even(int * x) { return !Odd(x[1]); }
void Init(int *x, const char *fileName) {
int i;
char c;
memset(x,0,sizeof(x));
ifstream f(fileName);
f >> x[0]; cout << endl << x[0] << endl;
for (i = x[0]; i > 0; --i) {
f >> c; x[i] = c - '0'; cout << x[i];
}
f.close();
}
void Print(int * x) {
for (int i = x[0]; i > 0; --i) cout << x[i];
}

5.12 Hm f(n)
Tnh ga tr ca hm f(n) vi bin s nguyn n cho trc, 0 n 1.000.000.000 (1 t). Bit
f(0) = 0; f(1) = 1; f(2n) = f(n); f(2n+1) = f(n) + f(n+1).
Thut ton
Xt hm 3 bin g(n,a,b) = af(n) + bf(n+1). Ta c,
1) g(n,1,0) = 1.f(n) + 0.f(n+1) = f(n).
2) g(0,a,b) = af(0) + bf(1) = a.0 + b.1 = b.
3) g(2n,a,b) = af(2n) + bf(2n+1) = af(n) + bf(n) + bf(n+1) = (a+b)f(n) + bf(n+1) = g(n,a+b,b).
4) g(2n+1,a,b) = af(2n+1)+bf(2n+2) = af(n) + af(n+1) + bf(2(n+1)) = af(n) + af(n+1) + bf(n+1) =
af(n) + (a+b)f(n+1) = g(n,a,a+b).
T bn tnh cht trn ta thit k c hm f(n) nh sau:
tnh f(n) ta tnh g(n,a,b) vi a = 1, b = 0. tnh g(n) ta lp n khi n = 0. Nu n chn ta gi hm
g(n/2,a+b,b); ngc li, nu n l ta gi hm g(n/2,a,a+b). Khi n = 0 ta thu c f = g(0,a,b) = b.
(* Pascal *)
function f(n: longint): longint;
var a,b: longint;
begin
a := 1; b := 0;
while (n <> 0) do
begin
if odd(n) then b := b + a else a := a + b;
n := n div 2;
end;
f := b;
end;
// DevC++

int f(int n) {
int a = 1, b = 0;
while (n) {
if (n % 2 == 0) a += b;
else b += a;
n /= 2;
}
return b;
}
phc tp
log2(n) vng lp.
D liu test
f(100) = 7; f(101) = 19; f(1000000) = 191; f(1000000000) = 7623.

5.13 Hm h(n)
Tnh hm h(n) vi gi tr n cho trc 0 n 1.000.000 (1 triu). Bit
h(0) = 3; h(1) = 1; h(2n) = 2h(n); h(2n+1) = h(n) 2h(n+1).
Thut ton
Xt hm 3 bin g(n,a,b) = ah(n) + bh(n+1). Ta c,
1) g(n,1,0) = h(n).
2) g(0,a,b) = 3a + b.
3) g(2n,a,b) = g(n,2a+b,2b).
4) g(2n+1,a,b) = g(n,a,2b2a).
D liu test
h(100) = 176; h(101) = 128; h(1000000) = 3162112; h(1000001) = 1933312.

5.14 Rhythm
Vit hm Rhythm(s) cho ra dng iu ca xu k t s = (s1. s2,, sn) nh sau
Rhythm(s) = 1, nu cc k t trong s u bng nhau: s 1= s2== sn,
Rhythm(s) = 2, nu cc k t trong s to thnh dy tng cht: s1 < s2 << sn,
Rhythm(s) = 3, nu cc k t trong s to thnh dy ng bin: s 1 s2 sn,
Rhythm(s) = 4, nu cc k t trong s to thnh dy gim cht: s 1 > s2 > > sn,
Rhythm(s) = 5, nu cc k t trong s to thnh dy nghch bin: s1 s2 sn,
Rhythm(s) = 0, nu khng xy ra cc tnh hung trn,
Kt qu c chn u tin cho cc gi tr nh. Th d, Rhythm("'aaaaa") = 1, trong khi cc tnh hung 3
v 5 cng tha. Bit 2 n 255.
Thut ton

Ta s dng 3 bin m b (bng), t (tng), g (gim) v duyt tun t xu s ghi nhn cc tnh hung khi di
chuyn t phn t si sang phn t tip theo si+1. C th l ta gn
b = 1 nu si = si+1,
t = 1 nu si < si+1,
g = 1 nu si > si+1.
Gi tr ca hm Rhythm chnh l s nguyn c dng biu din nh phn
(g,t,b). C th l vi 5 trng hp u ta c
Rhythm = 4*g + 2*t + b
Hai trng hp cui ng vi cc tr 6 v 7 c chuyn v 0.
Tm li, ta c
Rhythm = ((4*g + 2*t + b) mod 7) mod 6

g
0
0
0
1
1
1
1

t
0
1
1
0
0
1
1

phc tp. c n.
(* Rhythm.pas *)
uses crt;
function Rhythm(s: string): integer;
var i, g, t, b: integer;
begin
g := 0; t := 0; b := 0;
for i := 2 to length(s) do
if s[i] = s[i-1] then b := 1
else if s[i] > s[i-1] then t := 1
else { s[i] < s[i-1] } g := 1;
Rhythm := ((4*g + 2*t + b) mod 7 mod 6);
end;
BEGIN
writeln(Rhythm('aabccdx')); { 3 }
readln;
END.
// Rhythm.cpp
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
using namespace std;
// P R O T O T Y P E S
int Rhythm(char *);
// I M P L E M E N T A T I O N
int main() {
cout << endl << Rhythm("aabccdxxxz") << endl; // 3
cout << endl << " Fini ";
cin.get();
return 0;
}
int Rhythm(char * s) {
int g, t, b, i, n;
g = t = b = 0; n = strlen(s);
for (i = 1; i < n; ++i)
if (s[i] == s[i-1]) b = 1;
else if (s[i] > s[i-1]) t = 1;
else g = 1;
return ((4*g + 2*t + b) % 7) % 6;
}

5.15 Cc

b
1
0
1
0
1
0
1

Rhythm
1
2
3
4
5
60
70

Mt ch cc my c th nhy k bc vi di khc nhau (b1, b2, ..., bk) trn on ng thng. t cc


trn on ng thng ti vch xut pht 0. Cho bit s cch nhy cc n c im N.
Th d, s bc k = 2, b1 = 2, b2 = 3, on ng di N = 8.
C 4 cch: (2,2,2,2) (2, 3, 3) (3, 3, 2) (3, 2, 3).
Thut ton: Quy hoch ng.
Gi S(n) l s cch cc vt on ng di n. Da theo bc nhy u tin ta chia ton b cc phng
n nhy ca cc thnh k nhm khng giao nhau. Nh vy,
Nhm 1 s gm cc phng n bt u bng bc nhy di b 1, tc l gm cc phng n dng
(b1,...). Sau bc nhy u tin, cc vt on ng b1, on ng cn li s l nb1, do
tng s phng n ca nhm ny s l S(nb1).
Nhm 2 s gm cc phng n bt u bng bc nhy di b2, tc l gm cc phng n dng
(b2,...). Sau bc nhy u tin, cc vt on ng b2, on ng cn li s l nb2, do
tng s phng n ca nhm ny s l S(nb2).
...
Nhm i s gm cc phng n bt u bng bc nhy di bi, tc l gm cc phng n dng
(bi,...). Sau bc nhy u tin, cc vt on ng bi, on ng cn li s l nbi, do tng
s phng n ca nhm ny s l S(nbi).
...
Nhm k s gm cc phng n bt u bng bc nhy di b k, tc l gm cc phng n dng
(bk,...). Sau bc nhy u tin cc vt on ng b k, on ng cn li s l nbk, do tng
s phng n ca nhm ny s l S(nbk).
D nhin, bc u tin l bi s c chn nu bi n.
Vy ta c,
S(n) = { S(nbi) | n bi i = 1, 2, , k }
(*)
rng khi on ng cn vt c chiu di n = 0 th cc c 1 cch nhy (l ng yn), do S(0)
= 1. Ngoi ra ta quy nh S(n) = 0 nu n < 0.
S dng mng s ta tnh dn cc tr s[0] = 1; s[1], s[2], ..., s[n] theo h thc (*) ni trn. Kt qu c
lu trong s[n].
phc tp Vi mi gi tr n ta tnh k bc nhy, vy phc tp thi gian c k.n.
Cc chng trnh di y c d liu t input file "coc.inp" gm cc s k, n v di cc bc nhy b i, i
= 1, 2, ..., k. Kt qu c hin th trn mn hnh.
(* Coc.pas *)
uses crt;
const
fn = 'coc.inp';
maxk = 10; maxn = 50;
type mi1 = array[0..maxk] of integer;
ml1 = array[0..maxn] of longint;
var
k, n: integer;
b: mi1;
s: ml1;
procedure Doc;
var f: text; i: integer;
begin
assign(f,fn); reset(f);
read(f,k, n);
for i := 1 to k do read(f,b[i]);
close(f);
end;
procedure TinhS(d: integer);
var i: integer; v: longint;
begin
v := 0;
for i := 1 to k do
if (d >= b[i]) then v := v + s[d-b[i]];
s[d] := v;
end;
function XuLi: longint;
var d: integer;

begin
s[0] := 1;
for d := 1 to n do TinhS(d);
XuLi := s[n];
end;
BEGIN
Doc;
writeln(#13#10, XuLi);
readln;
END.

// DevC++: Coc.cpp
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
// D A T A A N D V A R I A B L E
const char BL = ' ';
int b[10];
int s[50];
int n, k;
void Doc();
int XuLi();
void TinhS(int);
int main(){
Doc();
cout << endl << XuLi() << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void Doc() {
ifstream f("Coc.inp");
f >> k >> n;
for (int i = 1; i <= k; ++i) f >> b[i];
}
int XuLi() {
s[0] = 1;
for (int d = 1; d <= n; ++d)
TinhS(d);
return s[n];
}
void TinhS(int d) {
int v = 0;
for (int j = 1; j <= k; ++j)
if (d >= b[j]) v += s[d-b[j]];
s[d] = v;
}
Ch
Nu ta sp tng mng b th ch cn duyt n khi b[i] > d.

5.16 Tr tin
Ucraina
Ngn hng c m loi tin giy mnh gi khc nhau b1 = 1, b2, ..., bk vi s lng khng hn ch. Cn chn
t nht l bao nhiu t tin c tng bng t cho trc.
Th d. C m = 4 loi tin mnh gi ln lt l 1, 2, 7 v 10 quan tin. Cn tr li t = 14 quan. Ta chn 2 t
tin mnh gi 7 quan.
Thut ton
Gi s(t) l s t tin t nht c tng bng t. Nu trong s ny c t tin mnh gi b i th tng s cn li l tbi
v do s t tin cn phi tr nt l s(tbi). Phng n ti u khi s l

s(t) = min { s(tbi)+1 | i = 1, 2, ... , m; bi t }


ci t ta dng mng s v tnh ln lt cc gi tr s[1], s[2], ... , s[t]. Kt qu c hin th trn mn hnh
l s[t].
phc tp: tm.
Ch iu kin c loi tin mnh gi 1 vi s lng khng hn ch m bo rng bi ton lun lun c
nghim. Tht vy, trong trng hp xu nht ta c th dng t t tin mnh gi 1 quan tr li.
(* money.pas *)
uses crt;
const fn = 'money.inp'; bl = #32; nl = #13#10;
var b: array[0..31] of integer;
s: array[0..1001] of integer;
m,t: integer;
procedure Doc;
var f: text; i: integer;
begin
assign(f,fn); reset(f);
read(f,m,t);
writeln(nl,m,bl,t);
for i := 1 to m do
begin
read(f,b[i]);
write(b[i],bl);
end;
close(f);
end;
function Min(a,b: integer): integer;
begin if a < b then Min := a else Min := b end;
procedure Tinhs(d: integer);
var i: integer;
begin
s[d] := d;
for i := 2 to m do
if (d >= b[i]) then s[d] := Min(s[d],s[d-b[i]]+1);
end;
function XuLi: integer;
var i: integer;
begin
for i := 1 to t do Tinhs(i);
XuLi := s[t];
end;
BEGIN
Doc;
writeln(nl,XuLi);
writeln(nl,' Fini'); readln;
END.
// DevC++: money.cpp
#include <string.h>
#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 = "money.inp";
int b[31]; // cac loai menh gia
int s[1001];
int m, t;
// P R O T O T Y P E S
void Doc();
int XuLi();
void Tinhs(int);

// I M P L E M E N T A T I O N
int main() {
Doc();
cout << endl << XuLi() << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
void Doc() {
int i;
ifstream f(fn);
f >> m >> t ;
cout << endl << m << " " << t << endl;
for ( i = 1; i < m; ++i) {
f >> b[i];
cout << b[i] << " ";
}
f.close();
}
int XuLi() {
for (int i = 1; i <= t; ++i) Tinhs(i);
return s[t];
}
int Min(int a, int b) {
return (a < b) ? a : b;
}
void Tinhs(int d) {
s[d] = d;
for (int i = 2; i <= m; ++i)
if (d >= b[i]) s[d] = Min(s[d], s[d-b[i]]+1);
}
Ch
Nu ta sp tng mng b th ch cn duyt n khi b[i] > d.

5.17 Game
Bulgaria
y l tr chi mt ngi tm gi l bn Vova vi hai dy s nguyn dng: a gm n > 1 phn t v b
gm m > 1 phn t. Vova phi thc hin cc thao tc sau y:
Chia mi dy a v b thnh k 1 nhm, mi nhm gm dy cc phn t ng lin nhau, s phn t
ca mi nhm c th khc nhau nhng ti thiu phi l 1. S k do Vova t quyt nh; M s cc
nhm l 1, 2, ... , k;
Vi mi nhm i trong dy a Vova phi tnh tng c = c1 + c2 + + ck,
trong
ci = (siui)(tivi), i = 1, 2, , k;
si l tng cc phn t ca nhm i trong dy a;
ui l s phn t ca nhm i trong dy a;
ti l tng cc phn t ca nhm i trong dy b;
vi l s phn t ca nhm i trong dy b;
Hy cho bit gi tr min ca c.
D liu vo: text file VOVA.INP
Dng u tin: 2 s n v m;
Tip n l n phn t ca dy a;
Tip n l m phn t ca dy b.
Cc s cng dng cch nhau qua du cch.

D liu ra: text file


VOVA.OUT
Cha gi tr min c.

VOVA.INP
3 2
3 7 4
5 2

VOVA.OUT
17

Gii thch
Vi th d trn, Vova xt cc phng n sau:
Phng n 1: Chn k = 1. Khi mi dy t tho thnh mt nhm: a = (3,7,4); b = (5,2).
Thao tc trn dy a: s1 = 3+7+4 = 14; u1 = 3;
Thao tc trn dy b: t1 = 5+2 = 7; v1 = 2;

c = c1 = (s1 u1)(t1v1) = (143)(72) = 115 = 55.


Phng n 2: Chn k = 2. Khi mi dy c ng 2 nhm: a = (3)(7,4); b = (5)(2) hoc a = (3,7)(4); b =
(5)(2) . Ta xt ln lt tng phng n con 2.1 v 2.2.
Phng n 2.1: a = (3)(7,4); b = (5)(2)
Thao tc trn dy a: s1 = 3; u1 = 1; s2 = 7+4 = 11; u2 = 2;
Thao tc trn dy b: t1 = 5; v1 = 1; t2 = 2; v2= 1;
c1 = (s1 u1)(t1v1) = (31)(51) = 24 = 8;
c2 = (s2 u2)(t2v2) = (112)(21) = 91 = 9;
c = c1 + c2 = 8 + 9 = 17.
Phng n 2.2: a = (3,7)(4); b = (5)(2)
Thao tc trn dy a: s1 = 3+7 = 10; u1 = 2; s2 = 4; u2 = 1;
Thao tc trn dy b: t1 = 5; v1 = 1; t2 = 2; v2= 1;
c1 = (s1 u1)(t1v1) = (102)(51) = 84 = 32;
c2 = (s2 u2)(t2v2) = (41)(21) = 31 = 3;
c = c1 + c2 = 32 + 3 = 35.
Vy cmin = min(55, 17, 35) = 17.
Thut ton
Nhn xt 1. Ta c th gim mi phn t ca a v b xung 1 n v. Khi cng thc tnh ci s c rt
gn thnh ci = siti.
Nhn xt 2. Mun t tr ti u cmin th trong nhm cui cng, nhm th k ca a v b khng th cha
ng thi hn 1 phn t.
Tht vy, ga s hai nhm cui ca dy a v b, nhm th k, u cha hn 1 phn t. Ta gi phng n ny
l P1. Ta xy dng phng n P2 gm k+1 nhm nh sau. Tch hai nhm cui ca a v b thnh hai nhm
nh v gi tng ca cc nhm ln lt l A+B cho nhm ca dy a v C+D cho nhm ca dy b. Khi
(A+B)(C+D) = AC + AD + BC + BD > AC + BD. T y suy ra phng n phn nhm P2 vi k+1 nhm
s cho kt qu nh hn phng n phn nhm P 1 thnh k nhm nh trong bng di y:
Phng n P1: k nhm

Phng n P2: k+1 nhm

Dy a

s1, s2, , sk-1, (A+B)

s1, s2, , sk-1, A, B

Dy b

t1, t2, , tk-1, (C+D)

t1, t2, , tk-1, C, D

(A+B)(C+D) = AC + AD + BC + BD > AC + BD
Nh vy, t tr cmin, nhm th k ca mt trong 2 dy a hoc b phi cha ng 1 phn t. Ta k hiu
cho cc tnh hung ny l:

1:1 c hai nhm cui ca a v b u c ng 1 phn t;

1:N nhm cui ca dy a c ng 1 phn t , ca dy b c hn 1 phn t;

hoc

N:1 nhm cui ca dy a c hn 1 phn t, ca dy b c ng 1 phn t.

K hiu c(n,m) l gi tr cmin ca bi ton vi hai dy a(1..n) v b(1..m).


Vi tnh hung 1:1 ta c hai nhm cui l (an) v (bm), do
c(n,m) = c(n1,m1) + anbm
Vi tnh hung 1:N ta gi s c hai nhm cui l (an) v (bi ,bi+1, ... ,bm-1,bm), i < m. Ta c
an(bi + bi+1+ ... +bm-1+bm) = an(bi + bi+1+ ... +bm-1) + anbm , do
c(n,m) = c(n,m1) + anbm
Vi tnh hung N:1 ta gi s c hai nhm cui l (aj ,aj+1, ... ,an-1,an), j < n v (bm) . Xt tng t nh tnh
hung 1:N ta thu c
c(n,m) = c(n1,m) + anbm
Vy

c(n,m) = min { c(n1,m1) + anbm, c(n,m1) + anbm , c(n1,m) + anbm }, hay


c(n,m) = min { c(n1,m1) , c(n,m1) , c(n1,m) } + anbm
Khi n = 1, vi mi m 1, mi dy to thnh ng 1 nhm nn ta c
c(n,m) = a1(b1 + b2+ ... +bm-1+bm).
Tng t, khi m = 1, vi mi n 1, mi dy to thnh ng 1 nhm nn ta c
c(n,m) = (a1 + a2+ ... +an-1+an)b1.
ci t ta dng 2 mng 1 chiu c v d.
Khi c d liu bn nh gim ng lot 1 n v cho cc s trong hai dy a v b.
Mng c lc u c khi tr vi n = 1, c[j] = a[1]*(b[1] + ... + b[j]), j = 1..m vi nghi dy a c ng 1
phn t a[1] do lc u ch c 2 nhm (a[1]) v (b[1..j]).
Sau ta lp n1 ln mi ln lp th i ta tnh tr cho hm c(i,j), j = 1..m v ghi vo mng d vi
d[1] = c[1] +a[i]*b[1]
d[j] = min { c[j1], c[j], d[j1] } + a[i]*b[j], j = 2..m
(* Game.pas *)
uses crt;
const mn = 201;
fn = 'vova.inp'; gn = 'vova.out';
bl = #32; nl = #13#10;
type mi1 = array[0..mn] of integer;
var a,b,c,d: mi1;
n, m: integer;
function Min(a, b, c: integer): integer;
begin
if a > b then a := b;
if a < c then Min := a else Min := c;
end;
function Cmin: integer;
var i,j: integer;
begin
fillchar(c,sizeof(c),0); d := c;
{ Khoi tri: 2 day a[1] , b[1..m] }
for j := 1 to m do c[j] := c[j-1] + a[1]*b[j];
for i := 2 to n do
begin
d[1] := c[1] + a[i]*b[1];
for j := 2 to m do
d[j] := Min(c[j-1], c[j],d[j-1]) + a[i]*b[j];
c := d;
end;
Cmin := d[m];
end;
procedure Doc;
var i: integer;
f: text;
begin
assign(f,fn); reset(f);
read(f,n,m); writeln(nl,n, bl, m);
for i := 1 to n do
begin
read(f,a[i]); dec(a[i]); write(a[i],bl);
end;
writeln;
for i := 1 to m do
begin
read(f,b[i]); dec(b[i]); write(b[i],bl);
end;
close(f);
end;
procedure Ghi(v: integer);
var g: text;

begin
assign(g,gn); rewrite(g);
writeln(g,v); close(g);
end;
BEGIN
Doc;
Ghi(Cmin);
writeln(nl,' Fini');
readln;
END.
// DevC++: game.cpp
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
const int mn = 201;
const char * fn = "vova.inp";
const char * fn = "vova.out";
int a[mn], b[mn], c[mn], d[mn];
int n, m;
void Doc();
int Cmin();
int Min(int, int, int);
void Ghi(int);
main() {
Doc(); Ghi(Cmin());
cout << endl << " Fini "; cin.get();
return 0;
}
int Min(int x, int y, int z) {
if (x > y) x = y;
return (x < z) ? x : z;
}
int Cmin() {
int i,j;
memset(c,0,sizeof(c)); memset(d,0,sizeof(d));
for (j = 1; j <= m; ++j) c[j] = c[j-1] + a[1]*b[j];
for (i = 2; i <= n; ++i) {
d[1] = c[1] + a[i]*b[1];
for (j = 2; j <= m; ++j)
d[j] = Min(c[j-1], c[j],d[j-1]) + a[i]*b[j];
memcpy(c,d,sizeof(d));
}
return d[m];
}
void Doc() {
ifstream f(fn);
f >> n >> m; cout << endl << n << " " << m << endl;
int i;
for (i = 1; i <= n; ++i) {
f >> a[i]; --a[i];
cout << a[i] << " ";
}
cout << endl;
for (i = 1; i <= m; ++i) {
f >> b[i]; --b[i];
cout << b[i] << " ";
}
f.close();
}
void Ghi(int v) {
ofstream g(gn);

g << v;
g.close();
}

5.18 Robots
Mt khu nghin cu Robot c 3 phng th nghim l A, B v C b tr trn mt tuyn ng thng theo th
t nu. Mi phng u c th c 3 loi robot thng minh l robot m R, robot m xanh B v robot
m xanh l G. Ngi ta ra lnh cho cc robot phi t bn nhau thc hin nhim v sau y: di chuyn
v cc phng sao cho mi phng ch c mt loi robot v nng lng chi ph cho vic di chuyn l t nht.
Hy cng bn vi cc robot chn mt phng n ti u.
D liu vo: text file ROBOTS.INP
Dng th nht: hai s nguyn dng biu th khong cch AB v AC;
Dng th hai: ba s nguyn dng r b g cho bit chi ph nng lng ca mi loi robot R, B v G
di chuyn 1 n v khong cch;
Dng th ba: ba s nguyn khng m cho bit s lng robot mi loi R, B v G trong phng A;
Dng th t: tng t nh dng th ba, cha thng tin v phng B;
Dng th nm: tng t nh dng th ba, cha thng tin v phng C.
D liu ra: text file ROBOTS.OUT
Dng th nht: tng chi ph nng lng ti thiu cho cc robot di chuyn;
Dng th hai: mt hon v ca ba ch ci R, B, G vit lin nhau cho bit phng n ti u b tr cc
robot vo cc phng.
D liu trn cng dng cch nhau qua du cch.
ROBOTS.INP
1 3
3 1 2
2 1 2
1 4 3
2 2 1

ROBOTS.OUT
40
RGB

Gii thch Khong cch AB = 1; AC = 3 trn ng thng


ABC;
robot R cn 3, B cn 1 v G cn 2 n v nng lng di
chuyn 1 n v khong cch;
Phng A c 2 robot R, 1 robot B v 2 robot G;
Phng B c 1 robot R, 4 robot B v 3 robot G;
Phng C c 2 robot R, 2 robot B v 1 robot G.
Kt qu: Nu tp hp cc robot m R v phng A, cc
robot m xanh l G v phng B v cc robot m xanh B v
phng C th chi ph nng lng l ti thiu v bng 40.

Thut ton
Bi ny kh d gii v ch i hi khong vi chc ln tnh ton n gin. K hiu XYZ l mt phng n
b tr robot loi X vo phng A, loi Y vo phng B v loi Z vo phng C. Ta c tt c 6 phng n l
RBG, RGB, BRG, BGR, GRB v GBR. Ta tnh chi ph cho mi phng n ri chn phng n vi chi ph
min. Ta s dng cc hm h tr sau y:
Move(r, i, j) chi ph di chuyn ton b robot loi r hin c trong phng i sang phng j i, i, j = A,
B, C .
PhuongAn(r1, r2, r3) chi ph cho phng n a cc robot loi r1 v phng A, loi r2 v phng
B v robot loi r3 v phng C.
(* ROBOTS.PAS *)
uses crt;
const fn = 'ROBOTS.INP'; gn = 'ROBOTS.OUT';
bl = #32; nl = #13#10; NN = 3;
A = 1; B = 2; C = 3; { cac phong }
RR = 1; RB = 2; RG = 3; { mau mu cua robots }
type mi1 = array[0..NN] of integer;
mi2 = array[0..NN] of mi1;
var AB,AC: integer; { Khong cch }
energy: mi1; { energy[i] - chi ph nng lng ca robot loi i }
number: mi2;
{ number[i,j] - so luong robot loai j trong phong i }
procedure Doc;
var i,j: integer;
f: text;
begin

assign(f,fn); reset(f);
read(f,AB,AC);
write(nl,' Khoang cach: ',AB,bl,AC);
write(nl,' Nang luong: ');
for i := 1 to NN do
begin read(f,energy[i]); write(energy[i],bl); end;
writeln(nl, ' Phan bo: ');
for i := 1 to NN do
begin
writeln;
for j := 1 to NN do
begin read(f,number[i,j]); write(number[i,j],bl) end;
end;
close(f);
end;
(* Chi phi chuyen robot loai r tu phong i sang phong j *)
function Move(r, i, j: integer): integer;
var e: integer;
begin
e := energy[r]*number[i][r];
case i of
A: if (j = B) then e := e*AB
else if (j = C) then e := e*AC else e := 0;
B: if (j = A) then e := e*AB
else if (j = C) then e := e*(AC-AB) else e := 0;
C: if (j = A) then e := e*AC
else if (j = B) then e := e*(AC-AB) else e := 0;
end;
Move := e;
end;
function PhuongAn(r1, r2, r3: integer): integer;
begin
PhuongAn := Move(r1,B,A) + Move(r1,C,A)+
Move(r2,A,B) + Move(r2,C,B)+
Move(r3,A,C) + Move(r3,B,C);
end;
procedure XuLi;
var i, imin, p: integer; pa: array[1..6] of integer;
g: text;
begin
p := 1; { phuong an 1: RBG }
pa[p] := PhuongAn(RR,RB,RG);
inc(p); { phuong an 2: RGB }
pa[p] := PhuongAn(RR,RG,RB);
inc(p); { phuong an 3: BRG }
pa[p] := PhuongAn(RB,RR,RG);
inc(p); { phuong an 4: BGR }
pa[p] := PhuongAn(RB,RG,RR);
inc(p); { phuong an 5: GRB }
pa[p] := PhuongAn(RG,RR,RB);
inc(p); { phuong an 6: GBR }
pa[p] := PhuongAn(RG,RB,RR);
imin := 1;
for i := 1 to 6 do
if (pa[i] < pa[imin]) then imin := i;
assign(g,gn); rewrite(g);
writeln(g,pa[imin]);
case imin of
1: write(g,'RBG');
2: write(g,'RGB');
3: write(g,'BRG');
4: write(g,'BGR');
5: write(g,'GRB');

6: write(g,'GBR');
end;
close(g);
end;
BEGIN
Doc;
XuLi;
writeln(nl,' Fini'); readln;
END.

// DecC++: Robots.cpp
#include <fstream>
#include <string.h>
#include <iostream>
using namespace std;
const int A = 0; // Phong 0: A
const int B = 1; // Phong 1: B
const int C = 2; // Phong 2: C
const int RR = 0; // Red Robot
const int RB = 1; // Blue Robot
const int RG = 2; // Green Robot
const int NN = 3; // So loai Robot = 3
const char * fn = "robots.inp";
const char * gn = "robots.out";
const char bl = 32;
int energy[NN]; // chi phi nag luong
int number[NN][NN];
// numer[i][j] - so luong robot loai j trong phong i
int AB, AC; // Khoang cach AB, AC
int pa[6]; // cac phuong an
void Doc() {
int i, j;
ifstream f(fn);
f >> AB >> AC;
cout << endl << "Khoang cach: " << AB << bl << AC;
cout << endl << " Nang luong: ";
for (i = 0; i < NN; ++i) {
f >> energy[i];
cout << energy[i] << bl;
}
cout << endl << " Phan bo: ";
for (i = 0; i < NN; ++i) {
cout << endl;
for (j = 0; j < NN; ++j) {
f >> number[i][j];
cout << number[i][j] << bl;
}
}
f.close();
}
int Move(int r, int from, int to) {
// chi phoi chuyen robot r tu phong i sang phong j
int e = energy[r]*number[from][r];
switch(from) {
case A: if (to == B) return e*AB;
else if (to == C) return e*AC;
case B: if (to == A) return e*AB;
else if (to == C) return e*(AC-AB);
case C: if (to == A) return e*AC;
else if (to == B) return e*(AC-AB);
}
}

int PhuongAn(int r1, int r2, int r3) {


return (Move(r1,B,A)+Move(r1,C,A)+
Move(r2,A,B)+Move(r2,C,B)+
Move(r3,A,C)+Move(r3,B,C));
}
void XuLi() {
int p, i, imin;
p = 0; // phuong an 0: RBG
pa[p] = PhuongAn(RR,RB,RG);
cout << endl << "RBG: " << pa[p];
++p; // phuong an 1: RGB
pa[p] = PhuongAn(RR,RG,RB);
cout << endl << "RGB: " << pa[p];
++p; // phuong an 2: BRG
pa[p] = PhuongAn(RB,RR,RG);
cout << endl << "BRG: " << pa[p];
++p; // phuong an 3: BGR
pa[p] = PhuongAn(RB,RG,RR);
cout << endl << "BGR: " << pa[p];
++p; // phuong an 4: GRB
pa[p] = PhuongAn(RG,RR,RB);
cout << endl << "GRB: " << pa[p];
++p; // phuong an 5: GBR
pa[p] = PhuongAn(RG,RB,RR);
cout << endl << "GBR: " << pa[p];
imin = 0;
for (i = 1; i < 6; ++i)
if (pa[i] < pa[imin]) imin = i;
ofstream g(gn);
g << pa[imin] << endl;
switch (imin) {
case 0: g << "RBG"; break;
case 1: g << "RGB"; break;
case 2: g << "BRG"; break;
case 3: g << "BGR"; break;
case 4: g << "GRB"; break;
case 5: g << "GBR"; break;
}
g.close();
}
main(){
Doc();
XuLi();
cout << endl << " Fini"; cin.get();
return 0;
}
Giao tha 2010

You might also like