You are on page 1of 161

1

T SCH TRI THC DUY TN




NGUY N XU N HUY






SNG TO
TRONG THUT TON
V
LP TR NH

v i ng n ng Pa s c a l v C#
T p 2


T u y n c c b i t o n T i n n n g c a o
c h o h c s i n h v s i n h v i n g i i

2



MC LC .

Chng 1 Cc bi ton v on thng ............................................................................................ 4
Bi 1.1 on ri 1 ........................................................................................................................... 4
Bi 1.2 on gi 1 .......................................................................................................................... 8
Bi 1.3 on gi 2 .........................................................................................................................11
Bi 1.4 on gi 3 .........................................................................................................................13
Bi 1.5 on bao nhau 1 ................................................................................................................16
Bi 1.6 on bao nhau 2 ..............................................................................................................19
Bi 1.7 Ph on 1 ........................................................................................................................21
Bi 1.8 Xanh tm vng 1 ...........................................................................................................24
Bi 1.9 Xanh tm vng 2 ..........................................................................................................27
Bi 1.10 Ph on 2 .....................................................................................................................30
Bi 1.11 on ri 2 ......................................................................................................................34
Bi 1.12 Ghp hnh ch nht .........................................................................................................35
Bi 1.13 Xanh ...........................................................................................................................37
Bi 1.14 Xp on .........................................................................................................................39
Bi 1.15 Cc hnh ch nht ..........................................................................................................41
Bi 1.16 Cc tam gic vung cn .................................................................................................46
Chng 2 Cc hm Next ................................................................................................................52
Bi 2.1 S st sau cng cao .......................................................................................................52
Bi 2.2 S st sau cng ch s ......................................................................................................54
Bi 2.3 Cc hon v ........................................................................................................................55
Bi 2.4 T hp ...............................................................................................................................58
Bi 2.5 S Kapreka ........................................................................................................................61
Bi 2.6 Kha vng ..........................................................................................................................66
Bi 2.7 Tr tin ...............................................................................................................................69
Bi 2.8 Dy Farey ..........................................................................................................................72
Bi 2.9 Qy Mi .............................................................................................................................77
Bi 2.10 Tng on .......................................................................................................................79
Bi 2.11 on khng gim di nht ..............................................................................................82
Bi 2.12 on n iu di nht ....................................................................................................84
Bi 2.13 Ly tha 2, 3 v 5 ............................................................................................................87
Chng 3 Tr chi ...........................................................................................................................89
Bi 3.1. Bc si A ..........................................................................................................................90
Bi 3.2. Bc si B ..........................................................................................................................92
Bi 3.3. Bc si C ..........................................................................................................................94
Bi 3.4. Chia on ..........................................................................................................................97
Bi 3.5. Bc si D ..........................................................................................................................97
Bi 3.6. Bc si E ...........................................................................................................................99
Bi 3.7. Bc si F .........................................................................................................................100
Bi 3.8. Chia Hnh ch nht .........................................................................................................102
Bi 3.9. Bc si G ........................................................................................................................103
Bi 3.10. Chia Hnh hp ...............................................................................................................103

3
Bi 3.11. Tr chi NIM ................................................................................................................104
Bi 3.12. C bng .........................................................................................................................106
Bi 3.13. C y ...........................................................................................................................113
Bi 3.14. Bc si H ......................................................................................................................114
Chng 4 Cc thut ton sp t ................................................................................................115
4.1 C tam ti ...............................................................................................................................115
4.2 Li tam gic u ...................................................................................................................117
4.3 Dng biu din ca giai tha ..................................................................................................121
4.4 Xp si ...................................................................................................................................127
4.5 Dy cc hon v ......................................................................................................................130
4.6 B bi .....................................................................................................................................134
4.7 Thun th ................................................................................................................................141
4.8 Cc nh khoa hc ...................................................................................................................144
4.9 Chn chic ng h .................................................................................................................152
4.10 S duy nht ...........................................................................................................................159

4
Chng 1
Cc bi ton v on thng
Bn cn ch c k bi. C nhng bi mi xem ta thy ta ta nh nhau nhng kt qu l khc
nhau. in hnh l nhng bi ti u ha, tc l nhng bi tm max hay min ca mt hm. Cc rng buc
ch khc nhau i cht nhng kh s th li khc xa nhau.
Bi 1.1 on ri 1
Cho N on thng vi cc im u a
i
v im cui b
i
l nhng s nguyn trong khong
1000..1000, a
i
< b
i
. Lit k s lng ti a K on thng khng giao nhau. Hai on thng [a,b] v [c,d]
c coi l khng giao nhau nu xp chng trn cng mt trc s, chng khng c im chung. iu kin
ny i hi: b < c hoc d < a.

DOAN.INP DOAN.OUT D liu vo: tp vn bn DOAN.INP
Dng u tin: s t nhin N, 1 < N s 1000.
Dng th i trong N dng tip theo, mi dng cha hai
s nguyn a
i
b
i
cch nhau qua du cch, biu th im u v
im cui ca on th i, i = 1..N.
D liu ra: tp vn bn DOAN.OUT
Dng u tin: s t nhin K.
K dng tip theo, mi dng mt s t nhin v th hin
ch s ca cc on ri nhau tm c.
Th d bn cho bit ti a c 5 on ri nhau l 1, 2, 7,
3 v 4.


8
2 3
4 5
10 12
13 15
1 9
2 5
6 8
7 15


5
1
2
7
3
4


Thut ton
Phng php: tham.
1. Sp cc on tng theo u phi b.
2. Khi tr: Ly on 1, t r = b
1
l u phi ca on ny
3. Vi mi on j := 2..N tip theo xt:
Nu u tri ca on j, a
j
> r th ly on j a vo kt qu
v chnh r l u phi ca on j, r := b
j
.
phc tp: c NlogN chi ph cho quick sort.

5
(* Pascal *)
(*===========================================
Doan roi 1: Liet ke toi da cac doan thang
khong giao nhau
===========================================*)
program DoanRoi1;
uses crt;
const mn = 1001; bl = #32 {Du cch}; nl = #13#10 {Xung dng};
fn = 'doan.inp'; gn = 'doan.out';
type { M t mt on }
KieuDoan = record
a,b: integer;
id: integer; { Ch s on }
end;
md1 = array[0..mn] of KieuDoan;
mi1 = array[0..mn] of integer;
var n,m,r: integer; { n s lng on }
{ m s lng on c chn }
{ r u phi ang duyt }
d: md1; { cc on d[1..n] }
f,g: text;
c: mi1; { mng cha kt qa }
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f); readln(f,n);
for i := 1 to n do
begin
read(f,d[i].a,d[i].b); d[i].id := i;
end;
close(f);
end;
(*---------------------------------
Sp tng cc on d[t..p] theo
u phi b.
---------------------------------*)
procedure Qsort(t,p: integer);
var i,j,m: integer;
x: KieuDoan;
begin
i := t; j := p; m := d[(i + j) div 2].b;
while (i <= j) do
begin
while (d[i].b < m) do i := i + 1;
while (m < d[j].b) do j := j - 1;
if (i <= j) then
begin
x := d[i]; d[i] := d[j]; d[j] := x;
i := i + 1; j := j - 1;
end;
end;
if (t < j) then Qsort(t,j);
if (i < p) then Qsort(i,p);
end;
procedure XuLi;
var i: integer;

6
begin
m := 1; c[m] := 1; { a on 1 vo kt qu }
r := d[m].b; { u phi ca on cui trong kt qu }
for i := 2 to n do
if (r < d[i].a) then
begin
m := m + 1; c[m] := i; r := d[i].b;
end;
end;
procedure Ghi;
var i: integer;
begin
assign(g,gn); rewrite(g); writeln(g,m);
for i := 1 to m do writeln(g,d[c[i]].id);
close(g);
end;
BEGIN
Doc; Qsort(1,n); XuLi; Ghi;
END.
// C#
using System;
using System.IO;
using System.Collections;
/*===============================================
* Doan Roi 1: Lit k ti a k on ri nhau *
===============================================*/
namespace SangTao2 {
class DoanRoi1 {
static public Doan[] d;
static int n; // s on
static int m; // s on c chn cho kt qu
static int[] c; // lu kt qu
const string fn = "doan.inp";
const string gn = "doan.out";
static void Main(string[] args) {
Doc(); QSortB(d,0,n-1);
XuLi(); Ghi(); XemKetQua();
Console.WriteLine("\n Fini "); Console.ReadLine();
}
static public void Doc() {
StreamReader f = File.OpenText(fn);
string s = f.ReadToEnd(); f.Close();
String[] ss = s.Split(
new char[] { ' ', '\n', '\r', '\t' },
StringSplitOptions.RemoveEmptyEntries);
int[] a = Array.ConvertAll(ss,
new Converter<string, int>(int.Parse));
n = a[0]; // so doan
d = new Doan[n];
int j = 1;
for (int i = 0; i < n; ++i, j += 2) // c on i
d[i] = new Doan(a[j], a[j + 1], i + 1);
} // Doc
static public void XuLi() {
m = 0;

7
c = new int[n];
c[m++] = 0; // chn on 0
int r = d[0].b; // thit lp gii hn phi
for (int i = 1; i < n; ++i)
if (r < d[i].a) { c[m++] = i; r = d[i].b; }
} // XuLi
// Sp tng cc on d[t..p] theo u phi b
static public void QSortB(Doan[] d, int t, int p) {
int i = t, j = p, m = d[(i + j) / 2].b;
while (i <= j) {
while (d[i].b < m) ++i;
while (d[j].b > m) --j;
if (i <= j) {
Doan x = d[i]; d[i] = d[j]; d[j] = x;
++i; --j;
}
}
if (t < j) QSortB(d, t, j);
if (i < p) QSortB(d, i, p);
}
static public void Ghi() {
StreamWriter g = File.CreateText(gn);
g.WriteLine(m);
for (int i = 0; i < m; ++i) g.WriteLine(d[c[i]].id);
g.Close();
}
// Hin th li cc files input, output kim tra
static public void XemKetQua() {
Console.WriteLine("\n Input " + fn);
Console.WriteLine(File.ReadAllText(fn));
Console.WriteLine("\n Output " + gn);
Console.WriteLine(File.ReadAllText(gn));
}
}// DoanRoi1
public struct Doan { // M t mt on
public int a, b, id;
public Doan(int x1,int x2,int z) // To on mi
{ a = x1; b = x2; id = z; }
} // Doan
} // SangTao2
Gii thch chng trnh C#
1. Khai bo file text f, m file tn fn = doan.inp c ton b d liu vo bin string
s ri ng file li.
StreamReader f = File.OpenText(fn);
string s = f.ReadToEnd(); f.Close();
2. Tch string s thnh mng cc string ss[i] theo cc du ngn cch khai bo trong new
char [], loi b cc string rng.
Trong mt dng vn bn thng cha cc du ngn cch sau y (gi l cc du trng)
' ' - du cch
'\n' - du ht dng (du xung dng)
'\r' - du v u dng (du ENTER/RETURN)
'\t' - du tab

8
string[] ss = s.Split(new char [] { ' ', '\n', '\r', '\t' },
StringSplitOptions.RemoveEmptyEntries);
3. Chuyn i mi string ss[i] thnh s nguyn v ghi trong mng nguyn a
int[] a = Array.ConvertAll(ss,
new Converter<string, int>(int.Parse));
Sau bc 3 d liu trong file doan.inp c c vo mng a[0..n-1].
4. Ly s lng on : n = a[0];
5. Xin cp pht n con tr kiu Doan : d = new Doan[n];
6. Cp pht v khi tr cho mi on i = 0..n-1. on i c ch s l i+1:
int j = 1;
for (int i = 0; i < n; ++i, j += 2) // doc doan i
{ d[i] = new Doan(a[j], a[j + 1], i + 1); }
C nhiu phng thc c/ghi cc text file. Bn cn la chn v ghi nh mt phng thc m bn cm
thy tin li nht.
7. Bn c th t chc d liu Doan theo dng struct (bn ghi) hoc dng class (lp). im
khc nhau cn bn gia hai cu trc ny l, theo qui c ngm nh struct c truyn theo tr (by
val) cn class c truyn theo ch dn (by ref).
public struct Doan {
public int a, b; // dim u v im cui on
public int id; // ch s on
// phng thc to on
public Doan(int x1, int x2, int z)
{ a = x1; b = x2; id = z; }
}
Bi 1.2 on gi 1
Cho N on thng trn trc s vi cc im u a
i
v im cui b
i
l nhng s nguyn trong khong
1000..1000, a
i
< b
i
. Hy tm s lng ti a K on thng gi nhau lin tip. Hai on thng [a,b] v
[c,d] c gi l gi nhau nu xp chng trn cng mt trc s th im u on ny trng vi im cui
ca on kia, tc l c = b hoc d = a.

DOAN.INP DOAN.OUT D liu vo: tp vn bn DOAN.INP: xem on gi 1
D liu ra: tp vn bn DOAN.OUT
cha duy nht mt s t nhin K.
Th d ny cho bit c ti a 3 on gi nhau lin tip l
[1,3], [3,4] v [4,5].

5
2 7
1 3
7 9
3 4
4 5

3
Thut ton
Phng php: Quy hoch ng + Tham.
Gi s cc on c sp tng theo u phi b. K hiu c(i) l s lng ti a cc on thng gi
nhau to thnh mt dy nhn on i lm phn t cui dy (khi kho st cc on t 1..i). Ta c
c(1) =1,
Vi i = 2...N: c(i) = max { c(j) | 1 s j < i, on j k trc on i: b
j
= a
i
} + 1.

9
Li dng cc on sp tng theo u phi b, vi mi on i ta ch cn duyt ngc cc on j ng
trc on i cho n khi pht hin bt ng thc b
j
< a
i
.
Kt qu: K = max { c(i) | i = 1...n }.
phc tp: c N
2
v vi mi on ta phi duyt ti a tt c cc on ng trc on .
(* Pascal *)
(*============================
on Gi 1: S lng ti a
cc on gi nhau.
============================*)
program DoanGoi1;
uses crt;
const
mn = 1001; bl = #32; nl = #13#10;
fn = 'doan.inp'; gn = 'doan.out';
type
KieuDoan = record a,b: integer; end;
md1 = array[0..mn] of KieuDoan;
mi1 = array[0..mn] of integer;
var n,m: integer; { n s lng on, m s on c chn }
d: md1; { cc on d[1..n]}
f,g: text;
c: mi1; { c[i] = s lng max cc on gi nhau n i }
procedure Doc; t vit
procedure Qsort(t,p: integer);t vit
procedure XuLi;
var i,j: integer;
begin
c[1] := 1;
for i := 2 to n do { Tnh c[i] }
begin
c[i] := 0;
for j := i-1 downto 1 do
begin
if (d[j].b < d[i].a) { doan j khong noi voi i }
then break;
if (d[j].b = d[i].a) then { j noi voi i }
if (c[j] > c[i]) then c[i] := c[j];
end;
c[i] := c[i] + 1;
end;
end;
procedure Ket; { Tim c max va hien thi ket qua }
var i,imax: integer;
begin
assign(g,gn); rewrite(g);
imax := 1;
for i := 2 to n do
if (c[imax] < c[i]) then imax := i;
writeln(g,c[imax]); close(g);
end;
BEGIN
Doc; Qsort(1,n); XuLi; Ket;
END.

10
// C#
using System;
using System.IO;
using System.Collections;
/*===============================================
on Gi 1: S lng ti a cc on gi nhau
===============================================*/
namespace SangTao2 {
class DoanGoi1 {
static public Doan[] d; // cc on d[0..n-1]
static int n; // s on
static int m;// s max cc on gi nhau
const string fn = "doan.inp"; // input file
const string gn = "doan.out"; // output file
static void Main(string[] args) {
Doc(); QSortB(d,0,n-1);
XuLi(); Ghi();
XemKetQua(); Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void Doc(): t vit
// Sp tng cc on d[t..p] theo u phi b
static public void QSortB(Doan[]d,int t,int p): t vit
static public void XuLi() {
int[] c = new int[n];
// c[i] s lng max on gi ktthc ti on i
c[0] = 1; // ly on 0
int imax = 0;
for (int i = 1; i < n; ++i) {
c[i] = 0;
int jmax = i;
for (int j = i - 1; j >= 0; --j) {
if (d[j].b < d[i].a) break;
if (d[j].b == d[i].a)
if (c[j] > c[jmax]) jmax = j;
}
c[i] = c[jmax] + 1;
if (c[i] > c[imax]) imax = i;
}
m = c[imax];
}
static public void Ghi(){
StreamWriter g = File.CreateText(gn);
g.WriteLine(m); g.Close();
}
// Hien thi lai cac files input, output
static public void XemKetQua(): t vit
}// DoanGoi1
public struct Doan
{
public int a,b;
public Doan(int x1, int x2) { a = x1; b = x2; }
} // Doan
} // SangTao2
Ch thch

11
Trong bi ny ta khng cn s dng trng ch s ring id cho kiu on.
Trong phng n C# ta tranh th tm gi tr cmax = c[imax] sau mi ln tnh c[i].
Bi 1.3 on gi 2
Cho N on thng trn trc s vi cc im u a
i
v im cui b
i
l nhng s nguyn trong khong
1000..1000, a
i
< b
i
. Lit k ti a K on thng gi nhau lin tip.

DOAN.INP DOAN.OUT D liu vo: tp vn bn DOAN.INP: xem on gi 1
D liu ra: tp vn bn DOAN.OUT
Dng u tin: s t nhin K.
Tip n l K dng, mi dng cha mt s t nhin biu
th ch s ca on thng gi nhau lin tip trong dy tm c.
Th d ny cho bit ti a c 3 on 2, 4 v 5 to thnh
dy on gi nhau lin tip.


5
2 7
1 3
7 9
3 4
4 5

3
2
4
5

Thut ton
Tng t nh bi on gi 1 nhng cn to thm con tr trc. t[i] = j c ngha l on i
c gi sau on j. Th tc GiaiTrinh(i) lit k cc on gi lin tip t phi qua tri thc cht l
lit k theo chiu ngc cc phn t trong mng con tr trc t bt u t phn t th i. Gi s t c dng
sau,
t[2] = 0; t[4] = 2; t[5] = 4;
v gi s i = 5 l v tr t tr cmax, ta phi ghi vo file kt qu g dy cc on gi nhau lin tip
nh sau,
2 4 5
Ta ch vic gi quy mun nh sau
procedure GiaiTrinh(i: integer);
begin
if (i <> 0) then
begin GiaiTrinh(t[i]); writeln(g,d[i].id); end;
end;
phc tp: c N
2
.
(* Pascal *)
(*=============================================
Doan Goi 2: Liet ke toi da cac doan thang
goi nhau lin tiep
=============================================*)
program DoanGoi2;
uses crt;
const
mn = 1001; bl = #32; nl = #13#10;
fn = 'doan.inp'; gn = 'doan.out';
type
KieuDoan = record a,b,id: integer; end;
md1 = array[0..mn] of KieuDoan;
mi1 = array[0..mn] of integer;
var n,m: integer; { n - so luong doan, m - so doan duoc chon }
d: md1; // cac doan
0 0 1 2 3 4 5
0 2 4

12
f,g: text;
c: mi1; { c[i] = so luong max doan goi voi doan i }
t: mi1; { tro truoc }
procedure Doc: t vit
procedure Qsort(i1,i2: integer): t vit
procedure XuLi;
var i,j,jmax: integer;
begin
fillchar(t,sizeof(t),0); {Khi tr mng tr trc}
c[1] := 1;
for i := 2 to n do
begin
c[i] := 0; jmax := i;
for j := i-1 downto 1 do
begin
if (d[j].b < d[i].a) then break;
if (d[j].b = d[i].a) then
if (c[j] > c[jmax]) then jmax := j;
end;
c[i] := c[jmax]+1; t[i] := jmax;
end;
end;
procedure GiaiTrinh(i: integer): t vit;
procedure Ket;
var i,imax: integer;
begin
assign(g,gn);rewrite(g);
imax := 1;
for i := 2 to n do
if (c[imax] < c[i]) then imax := i;
writeln(g,c[imax]);
GiaiTrinh(imax);
close(g);
end;
BEGIN
Doc; Qsort(1,n); XuLi; Ket;
END.
// C#
using System;
using System.IO;
using System.Collections;
/*===============================================
* Doan Goi 2: Liet ke toi da cac doan goi nhau *
===============================================*/
namespace SangTao2 {
class DoanGoi2 {
static public Doan[] d;
static int n; // tong so doan
static int[] t; // tro truoc
const string fn = "doan.inp";
const string gn = "doan.out";
static void Main(string[] args){
Doc(); QSortB(d,0,n-1);
int m = 0; // so doan tim duoc
int imax = 0; // chi so doan cuoi trong day max

13
XuLi(ref imax, ref m); Ghi(imax,m);
XemKetQua(); Console.ReadLine();
}
static public void Doc(): t vit
static public void XuLi(ref int imax, ref int m) {
int [] c = new int[n];
t = new int[n];
Array.Clear(t, 0, t.Length);
t[0] = -1;
// c[i] - so luong doan goi ket thuc tai doan i
c[0] = 1; // lay doan 0
imax = 0;
for (int i = 1; i < n; ++i){
c[i] = 0;
int jmax = i;
for (int j = i - 1; j >= 0; --j){
if (d[j].b < d[i].a) break;
if (d[j].b == d[i].a)
if (c[j] > c[jmax]) jmax = j;
}
c[i] = c[jmax] + 1; t[i] = jmax;
if (c[i] > c[imax]) imax = i;
}
m = c[imax];
}
// Sap tang cac doan theo dau phai (b)
static public void QSortB(Doan[] d,int i1,int i2): t vit
static void Path(StreamWriter g, int imax) {
if (imax != -1)
{ Path(g,t[imax]); g.WriteLine(d[imax].id); }
}
static public void Ghi(int imax, int m){
StreamWriter g = File.CreateText(gn);
g.WriteLine(m); Path(g, imax); g.Close();
}
// Hien thi lai cac files input, output
static public void XemKetQua(): t vit
} // DoanGoi2
public struct Doan: t vit
} // SangTao2
Bi 1.4 on gi 3
Cho N on thng trn trc s vi cc im u a
i
v im cui b
i
l nhng s nguyn trong khong
1000..1000, a
i
< b
i
. i = 1..n. Lit k cc on thng gi nhau c tng chiu di C ln nht.


DOAN.INP

DOAN.OUT
D liu vo: tp vn bn DOAN.INP: xem bi on gi 1.

14

8
2 7
1 3
7 9
3 40
3 5
2 3
5 9
9 16


39
2
4


D liu ra: tp vn bn DOAN.OUT
Dng u tin: s t nhin C.
Mi dng tip theo cha mt s t nhin biu th ch s ca
on thng gi nhau lin tip trong dy tm c.
Th d ny cho bit hai on 2 v 4 to thnh dy on gi
nhau lin tip c tng chiu di max l 39.
Thut ton
Phng php: Quy hoch ng kt hp vi con tr trc t gii trnh kt qu.
Gi s cc on c sp tng theo u phi b. K hiu c(i) l tng chiu di ln nht cc on
thng gi nhau lin tip to thnh mt dy nhn on i lm phn t cui dy (khi kho st cc on t 1..i).
rng (b
i
a
i
) l chiu di on th i, ta c
c(1) = chiu di on 1 = b
1
a
1
,
Vi i = 2..N: c(i) = max { c(j) | 1 s j < i, on j k trc on i: b
j
= a
i
} + (b
i
a
i
),
Nu j l ch s t max th t t
i
= j.
phc tp: N
2
.
(* Pascal *)
(*=============================================
Doan Goi 3: Liet ke cac doan goi nhau
co tong chieu dai max
============================================*)
program DoanGoi3;
uses crt;
const
mn = 1001; bl = #32; nl = #13#10;
fn = 'doan.inp'; gn = 'doan.out';
type
KieuDoan = record a,b,id: integer; end;
md1 = array[0..mn] of KieuDoan;
mi1 = array[0..mn] of integer;
var n,m: integer; { n s lng on, m s on c chn }
d: md1;
f,g: text;
c: mi1; {c[i] = chieu dai max nhan i lam doan cuoi}
t: mi1; { tro truoc }
procedure Doc; t vit
procedure Qsort(l,r: integer); t vit
procedure XuLi;
var i,j,jmax: integer;
begin
fillchar(t,sizeof(t),0);{ Kh to mng tr trc }
c[1] := d[1].b - d[1].a; { Chieu dai doan 1 }
for i := 2 to n do
begin
c[i] := 0; jmax := i;
for j := i-1 downto 1 do
begin
if (d[j].b < d[i].a) then break;

15
if (d[j].b = d[i].a) then
if (c[j] > c[jmax]) then
jmax := j;
end;
c[i] := c[jmax] + (d[i].b - d[i].a); t[i] := jmax;
end;
end;
procedure GiaiTrinh(i: integer); t vit
procedure Ket; t vit
BEGIN
Doc; Qsort(1,n); XuLi; Ket;
END.
// C#
using System;
using System.IO;
using System.Collections;
/*================================================
* Doan Goi 3: Liet ke toi da cac doan goi nhau *
* co tong chieu dai max *
================================================*/
namespace SangTao2 {
class DoanGoi3 {
static public Doan[] d;
static int n; // tong so doan
static int[] t; // tro truoc
const string fn = "doan.inp";
const string gn = "doan.out";
static void Main(string[] args) {
Doc(); QSortB(d,0,n-1);
int maxlen = 0; // so doan tim duoc
int imax = 0; // chi so doan cuoi trong day max
XuLi(ref imax, ref maxlen);
Ghi(imax,maxlen);
XemKetQua(); Console.ReadLine();
}
static public void Doc(): t vit
static public void XuLi(ref int imax, ref int maxlen){
int [] c = new int[n];
t = new int[n];
Array.Clear(t, 0, t.Length);
t[0] = -1;
// c[i] - so luong doan goi ket thuc tai doan i
c[0] = d[0].b-d[0].a; // lay doan 0
imax = 0;
for (int i = 1; i < n; ++i) {
c[i] = 0;
int jmax = i; // Day dai nhat noi voi doan i
for (int j = i - 1; j >= 0; --j) {
if (d[j].b < d[i].a) break;
if (d[j].b == d[i].a)
if (c[j] > c[jmax]) jmax = j;
}
c[i] = c[jmax] + (d[i].b - d[i].a) ; t[i] = jmax;
if (c[i] > c[imax]) imax = i;
}

16
maxlen = c[imax];
}
// Sap tang cac doan theo dau phai (b)
static public void QSortB(Doan[] d, int t, int p): t vit
static void Path(StreamWriter g, int imax): t vit
static public void Ghi(int imax, int maxlen): t vit
// Hien thi lai cac files input, output
static public void XemKetQua(): t vit
}// DoanGoi3
public struct Doan: t vit
} // SangTao2
Bi 1.5 on bao nhau 1
Cho N on thng trn trc s vi cc im u a
i
v im cui b
i
l nhng s nguyn trong khong
1000..1000, a
i
< b
i
, i = 1..n. Tm K l s lng nhiu on nht to thnh mt dy cc on bao nhau lin
tip. Hai on [a,b] v [c,d] c gi l bao nhau nu on ny nm lt trong an kia, tc l a s c < d s
b hoc c s a < b s d.

DOAN.INP DOAN.OUT
D liu vo: tp vn bn DOAN.INP: xem bi trc
D liu ra: tp vn bn DOAN.OUT
cha duy nht mt s t nhin K.
Th d ny cho bit ti a c 3 on bao nhau l cc
on [-1,12] _ [8,11] _ [8,10].


6
-1 12
8 10
8 11
2 7
17 18
13 20

3


Thut ton
Phng php: Quy hoch ng.
Gi s cc on c sp tng theo u phi b nh sau. Nu hai on c cng u phi th on no
c u tri nh hn s c t sau. K hiu c(i) l s lng ln nht cc on bao nhau lin tip trong
on i. Ta c,
c(1) = 1,
Vi i = 2...N: c(i) = max { c(j) | 1 s j < i, on j lt trong on i: a
j
> a
i
} + 1,
phc tp: N
2
.
Hm SanhDoan(x,y) thit lp trt t gia hai on x v y nh sau:
Nu x.b < y.b cho kt qu 1, nu khng: xt tip
Nu x.b > y.b cho kt qu 1, nu khng: xt tip
Xt trng hp x.b = y.b.
o Nu x.a < y.a cho kt qu 1, nu khng: xt tip
o Nu x.a > y.a cho kt qu 1, nu khng: xt tip
o Hai on trng nhau: x.a = y.a v x.b = y.b cho kt qa 0.
(* Pascal *)
uses crt;
const MN = 1001; bl = #32; nl = #13#10;

17
fn = 'doan.inp'; gn = 'doan.out';
type
Doan = record a,b: integer; end;
MD1 = array[0..MN] of Doan;
MI1 = array[0..MN] of integer;
var f,g: text;
d: MD1; { cac doan }
n: integer; { so doan }
procedure Doc; t lm
function SanhDoan(x,y: Doan): integer;
begin
if (x.b < y.b) then begin SanhDoan := -1; exit end;
if (x.b > y.b) then begin SanhDoan := 1; exit end;
if (x.a < y.a) then begin SanhDoan := 1; exit end;
if (x.a > y.a) then begin SanhDoan := -1; exit end;
SanhDoan := 0;
end;
procedure QSortB(t,p: integer);
var i,j: integer; m,x: Doan;
begin
i := t; j := p; m := d[(i+j) div 2];
while (i <= j) do
begin
while (SanhDoan(d[i],m) < 0) do i := i+1;
while (SanhDoan(d[j],m) > 0) do j := j-1;
if (i <= j) then
begin
x := d[i]; d[i] := d[j]; d[j] := x;
i := i+1; j := j-1;
end;
end;
if (t < j) then QSortB(t,j);
if (i < p) then QSortB(i,p);
end;
function XuLi: integer;
var c: mi1; { c[i] so doan bao nhau max }
i,j,cmax: integer;
begin
cmax := 0;
for i := 1 to n do
begin
c[i] := 0;
for j := i-1 downto 1 do
begin
if (d[j].b <= d[i].a) then break;
if (d[j].a >= d[i].a) then
if (c[j] > c[i]) then c[i] := c[j];
end;
c[i] := c[i] + 1;
if (cmax < c[i]) then cmax := c[i];
end;
XuLi := cmax;
end;
procedure Ghi(k: integer);
begin
assign(g,gn); rewrite(g); writeln(g,k); close(g);
end;

18
BEGIN
Doc; QSortB(1,n); Ghi(XuLi); readln;
END.
// C#
using System;
using System.IO;
using System.Collections;
/*===============================================
Doan Bao 1: So luong toi da cac doan
bao nhau
===============================================*/
namespace SangTao2 {
class DoanBao1 {
static public Doan[] d; // cac doan
static int n; // tong so doan
const string fn = "doan.inp";
const string gn = "doan.out";
static void Main(string[] args){
Doc(); QSortB(d, 0, n - 1);
Ghi(XuLi());
XemKetQua(); Console.WriteLine("\n Fini");
Console.ReadLine();
}
static public void Doc(): t vit
static public int XuLi(){
int [] c = new int [n];
int cmax = 0;
for (int i = 0; i < n; ++i){
c[i] = 0;
for (int j = i-1; j >= 0; --j){
if (d[j].b <= d[i].a) break;
if (d[j].a >= d[i].a)
if (c[j] > c[i]) c[i] = c[j];
}
++c[i];
if (cmax < c[i]) cmax = c[i];
}
return cmax;
} // XuLi
static public int SanhDoan(Doan x, Doan y){
if (x.b > y.b) return 1;
if (x.b < y.b) return -1;
// x.b == y.b
if (x.a < y.a) return 1;
if (x.a > y.a) return -1;
return 0;
}
// Sap tang cac doan theo dau b
// Hai doan cung dau b: doan nao a nho dat sau
static public void QSortB(Doan[] d, int t, int p){
int i = t, j = p;
Doan m = new Doan(d[(i + j) / 2]);
while (i <= j){
while (SanhDoan(d[i],m) < 0) ++i;
while (SanhDoan(d[j],m) > 0) --j;

19
if (i <= j){
Doan x = d[i]; d[i] = d[j]; d[j] = x;
++i; --j;
}
}
if (t < j) QSortB(d, t, j);
if (i < p) QSortB(d, i, p);
}
static public void Ghi(int m){
File.WriteAllText(gn, m.ToString());
}
// Hien thi lai cac files input, output
static public void XemKetQua(): t vit
}// DoanBao1
public struct Doan: t vit
} // SangTao2
Bi 1.6 on bao nhau 2
Cho N on thng trn trc s vi cc im u a
i
v im cui b
i
l nhng s nguyn trong khong
1000..1000, a
i
< b
i
, i = 1..n. Lit k ti a K on bao nhau.

DOAN.INP DOAN.OUT
D liu vo: tp vn bn DOAN.INP: xem bi trc
D liu ra: tp vn bn DOAN.OUT
Dng u tin: s t nhin K.
Tip n l K dng, mi dng cha mt s t nhin l
ch s ca on trong dy tm c. Cc ch s c li k
theo trt t bao nhau t ln n nh.
Th d ny cho bit ti a c 3 on bao nhau l cc
on 1, 5 v 2: [-1,12] _ [8,11] _ [8,10].

6
-1 12
8 10
17 18
2 7
8 11
13 20

3
1
5
2



Thut ton
Ging bi on bao nhau 1. c danh sch on bao nhau ta dng mng tr t[1..n], t[i] tr n
on j l on nm trong on i v c[j] t gi tr max.
phc tp: N
2
.
(* Pascal *)
uses crt;
const MN = 1001; bl = #32; nl = #13#10;
fn = 'doan.inp'; gn = 'doan.out';
type
Doan = record a,b: integer; id: integer; end;
MD1 = array[0..MN] of Doan;
MI1 = array[0..MN] of integer;
var f,g: text;
d: MD1;
t: MI1; { tro truoc }
n: integer;
imax, k: integer;
procedure Doc; t lm
function SanhDoan(x,y: Doan): integer; t lm

20
procedure QSortB(t,p: integer): t lm
procedure XuLi;
var c: mi1;
i,j: integer;
begin
imax := 1;
for i := 1 to n do
begin
c[i] := 0; t[i] := 0;
for j := i-1 downto 1 do
begin
if (d[j].b <= d[i].a) then break;
if (d[j].a >= d[i].a) then
if (c[j] > c[i]) then
begin c[i] := c[j]; t[i] := j end;
end;
c[i] := c[i] + 1;
if (c[imax] < c[i]) then imax := i;
end;
k := c[imax];
end;
procedure Path(i: integer);
begin
if (i = 0) then exit;
writeln(g,d[i].id); Path(t[i]);
end;
procedure Ghi;
begin
assign(g,gn); rewrite(g); writeln(g,k);
path(imax); close(g);
end;
BEGIN
Doc; QSortB(1,n); XuLi; Ghi; readln;
END.
// C#
using System;
using System.IO;
using System.Collections;
/*===============================================
Doan Bao 2: Liet ke toi da cac doan
bao nhau
===============================================*/
namespace SangTao2 {
class DoanBao2 {
static public Doan[] d; // Cac doan
static public int [] t; // Con tro truoc
static int n; // tong so doan
const string fn = "doan.inp";
const string gn = "doan.out";
static void Main(string[] args){
Doc(); QSortB(d, 0, n - 1);
int k, imax;
XuLi(out k, out imax); Ghi(k, imax);
XemKetQua(); Console.WriteLine("\n Fini");
Console.ReadLine();

21
}
static public void Doc(): t lm
static public void XuLi(out int cmax, out int imax){
int [] c = new int [n];
t = new int[n];
imax = 0;
for (int i = 0; i < n; ++i){
c[i] = 0; t[i] = -1;
for (int j = i-1; j >= 0; --j){
if (d[j].b <= d[i].a) break;
if (d[j].a >= d[i].a)
if (c[j] > c[i])
{ c[i] = c[j]; t[i] = j; }
}
++c[i];
if (c[imax] < c[i]) imax = i;
}
cmax = c[imax];
} // XuLi
static public int SanhDoan(Doan x, Doan y): t lm
static public void QSortB(Doan[] d, int t, int p): t lm
static void Path(StreamWriter g, int imax){
if (imax != -1)
{ g.WriteLine(d[imax].id); Path(g, t[imax]); }
}
static public void Ghi(int k, int imax){
StreamWriter g = File.CreateText(gn);
g.WriteLine(k); Path(g, imax); g.Close();
}
static public void XemKetQua(): xem bi trc
}// DoanBao2
public struct Doan: t lm
} // SangTao2
Bi 1.7 Ph on 1
Cho N on thng trn trc s vi cc im u a
i
v im cui b
i
l nhng s nguyn trong khong
1000..1000, a
i
< b
i
. Hy ch ra t nht K on thng sao cho khi t chng trn trc s th c th ph kn
on [x, y] vi ta nguyn cho trc.

DOAN.INP DOAN.OUT D liu vo: tp vn bn DOAN.INP: xem bi trc
D liu ra: tp vn bn DOAN.OUT
Dng u tin: s K, nu v nghim K = 0.
Tip theo l K s t nhin biu th ch s ca cc on
thng ph kn on [x, y].
Th d ny cho bit t nht l 3 on 1, 3 v 4 s ph kn
on [3, 23].

5
3 23
1 15
3 10
8 20
17 25
2 7

3
1
3
4
Thut ton
Phng php: Tham

22
Sp cc on tng theo u phi b.
k : = 1; { ch s u tin }
v := x; { u tri ca on [x,y] }
Lp n khi v > y
Duyt ngc t N n k
Tm on j [a
j
, b
j
] u tin c u tri a
j
s v;
Nu khng tm c: v nghim;
Nu tm c:
Ghi nhn on j;
t li v := b
j
;
t li k := j+1;
phc tp: N
2
.
(* Pascal *)
(*========================================
Phu doan 1
Tm t nht K on c th ph kn
on [x,y] cho trc
=========================================*)
program PhuDoan1;
uses crt;
const
mn = 2002; bl = #32; nl = #13#10;
fn = 'doan.inp'; gn = 'doan.out';
type
KieuDoan = record
a,b: integer;
id: integer; { Ch s on }
end;
md1 = array[0..mn] of KieuDoan;
mi1 = array[0..mn] of integer;
var n: integer; { n - so luong doan }
d: md1; { cac doan }
f,g: text;
t: mi1;
x, y: integer; { Doan can phu }
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f); readln(f,n);
readln(f,x, y);
for i := 1 to n do
begin
readln(f,d[i].a,d[i].b);
d[i].id := i;
end;
close(f);
end;
procedure Qsort(l,r: integer): t vit
(*----------------------------------------
Duyet nguoc cac doan d[s..e]
tim doan i dau tien thoa d[i].a <= x
---------------------------------------*)

23
function Tim(s,e,x: integer): integer;
var i: integer;
begin
Tim := 0;
for i := e downto s do
if (d[i].a <= x) then
begin
Tim := i;
exit;
end;
end;
procedure Ket(k: integer): t vit
procedure XuLi;
var i,j,k,v: integer; { k - so doan tim duoc }
begin
v := x;
k := 0; t[k] := 0;
repeat
j := Tim(t[k]+1,n,v);
if (j = 0) then { Khong tim duoc }
begin Ket(0); { vo nghiem } exit; end;
v := d[j].b; k := k + 1; t[k] := j;
until (v >= y);
Ket(k); { co nghiem }
end;
BEGIN
doc; qsort(1,n); xuli;
END.
// C#
using System;
using System.IO;
using System.Collections;
/*===============================================
* Phu Doan 1: Liet ke toi thieu cac doan *
* phu doan [x,y] cho truoc *
===============================================*/
namespace SangTao2 {
class PhuDoan1 {
static public Doan[] d; // cac doan
static int n; // tong so doan
static int m;// so doan tim duoc
static int[] c; // luu ket qua cac doan duoc chon
const string fn = "doan.inp";
const string gn = "doan.out";
static int x, y; // doan [x,y] can phu

static void Main(string[] args) {
Doc(); QSortB(d, 0, n - 1);
m = XuLi(); Ghi();
XemKetQua(); Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void Doc() {
int[] a = Array.ConvertAll(File.ReadAllText(fn).
Split(new chae[] {' ','\n','\r','\t'},

24
StringSplitOptions.RemoveEmptyEntries),
new Converter<string, int>(int.Parse));
int j = 0;
n = a[j++]; // tong so doan
d = new Doan[n];
// Doc doan xy can phu
x = a[j++]; y = a[j++];
for (int i = 0; i < n; ++i, j += 2) // doc doan i
d[i] = new Doan(a[j], a[j + 1], i + 1);
} // Doc
static public int XuLi() {
c = new int [n];
int v = x; // dau trai doan [x,y]
int k = 0; // dem so doan tim duoc
int left = 0; // can trai
do {
int j = Tim(left, n - 1, v);
if (j == -1) return 0; // vo nghiem
c[k++] = j; // Tim duoc
left = j + 1;
v = d[j].b; // Chinh lai dau trai

} while (v < y);
return k;
} // XuLi
// Duyet nguoc cac doan d[s..e]
// tim doan dau tien i: d[k].a <= x
static public int Tim(int s, int e, int x) {
for (int i = e; i >= s; --i)
if (d[i].a <= x) return i;
return -1;
}
// Sap tang cac doan theo dau phai (b)
static public void QSortB(Doan[] d, int t, int p): t vit
static public void Ghi() : t vit
// Hien thi lai cac files input, output
static public void XemKetQua(): t vit
}// PhuDoan1
public struct Doan: t vit
} // SangTao2
Bi 1.8 Xanh tm vng 1
Cho 4 loi on thng sn cc mu xanh, , tm v vng, bao gm x on mu xanh mi on di
dx, d on mu mi on di dd, t on mu tm mi on di dt v v on mu vng mi on di dv.
Cc on thng cng mu th c cng chiu di. Hy chn mi loi mt s on thng ri xp ni nhau
theo chu vi thu c mt hnh ch nht c din tch ln nht vi cc cnh ln lt mang cc mu tnh
theo chiu quay ca kim ng h l xanh, , tm, vng. Cc i lng trong bi u l cc s nguyn
dng.

XDTV1.INP XDTV1.OUT

15 12
6 21

15120
15 4 12 3

xanh

v

25
14 15
10 28

n
g




tm

D liu vo: tp vn bn XDTV1.INP gm 4 dng, mi dng hai s nguyn dng vit cch nhau
Dng th nht: x dx
Dng th hai: d dd
Dng th ba: t dt
Dng th t: v dv
D liu ra: tp vn bn XDTV1.OUT
Dng u tin: Din tch ca hnh ch nht xanh - - tm - vng.
Dng th hai: 4 s cho bit s lng on thng cn chn theo mi loi mu ghp c hnh ch
nht din tch max.
Kt qu trn cho bit cn chn 15 on xanh, 4 on , 12 on tm v 3 on vng ghp thnh
hnh ch nht xanh tm vng vi din tch max l 15120 = (15*12)*(4*21) = (12*15)*(3*28).
Thut ton
Phng php: Tham.
Ta gi mt b xanh - tm l mt cp (nx,nt) trong nx l s t nht cc on mu xanh t lin tip
nhau trn ng thng to thnh on AB v nt l s t nht cc on mu tm t lin tip nhau trn ng
thng to thnh on CD sao cho AB = CD. Ta c ngay nx*dx = nt*dt. D dng tm c nx =
Bcnn(dx,dt)/dx v nt = Bcnn(dx,dt)/dt, trong Bcnn(a,b) l hm tnh bi chung nh nht ca hai s t
nhin a v b. Tng t ta tnh cho b - vng. Tip n ta tnh xem ti a c th ly c bao nhiu b
xanh - tm v b - vng. D thy S b xanh - tm = min(x div nx, t div nt). Tng t ta tnh cho b -
vng.
phc tp: O(1).
(* Pascal *)
(******************************************
Xanh Do Tim Vang 1
******************************************)
program xdtv1;
uses crt;
const
fn = 'xdtv1.inp'; gn = 'xdtv1.out'; bl = #32;
var
n: longint;
f,g: text;
x,d,t,v: longint; { so doan X D T V }
dx,dd,dt,dv: longint; { cheu dai moi doan }
nx,nt,nd,nv: longint; { so doan X D T V can chon }
procedure Doc;
begin
assign(f,fn); reset(f);
readln(f,x,dx); readln(f,d,dd); readln(f,t,dt); readln(f,v,dv);
close(f);
end;
function Ucln(a,b: longint): longint;
var r: longint;

26
begin
while (b <> 0) do
begin r := a mod b; a := b; b := r; end;
Ucln := a;
end;
(*------------------------------------
Bcnn(a,b) = (a * b)/Ucln(a,b)
-------------------------------------*)
function Bcnn(a,b: longint): longint;
begin Bcnn := a * (b div Ucln(a,b)); end;
function Min(a,b: longint): longint; t vit
procedure XuLi;
var b, nxt, ndv: longint;
begin
b := Bcnn(dx,dt);
nx := b div dx; { so doan xanh trong 1 bo xanh tim }
nt := b div dt; { so doan tim trong 1 bo xanh tim }
nxt := Min(x div nx, t div nt); { so bo xanh tim }
nx := nxt * nx; { so doan xanh can chon }
nt := nxt * nt; { so doan tim can chon }
b := Bcnn(dd,dv);
nd := b div dd; { so doan do trong 1 bo do vang }
nv := b div dv; { so doan vang trong 1 bo do vang }
ndv := Min(d div nd, v div nv);{ so bo do vang }
nd := ndv * nd; { so doan do can chon }
nv := ndv * nv; { so doan vang can chon }
end;
procedure Ghi;
begin
assign(g,gn); rewrite(g);
writeln(g,nx*dx*nd*dd);{ dien tich }
writeln(g,nx,bl,nd,bl,nt,bl,nv); { so doan moi loai }
close(g);
end;
BEGIN
Doc; XuLi; Ghi;
END.
// C#
using System;
using System.IO;
using System.Collections;
/*===============================================
Xanh Do Tim Vang 1
===============================================*/
namespace SangTao2 {
class Xdtv1 {
static int x, dx, d, dd, t, dt, v, dv;
static int nx, nd, nt, nv; // Dap so
const string fn = "xdtv1.inp";
const string gn = "xdtv1.out";
static void Main(string[] args) {
Doc(); XuLi(); Ghi();
XemKetQua(); Console.WriteLine("\n Fini");
Console.ReadLine();
}

27
static public void Doc(){
int[] a = Array.ConvertAll(File.ReadAllText(fn).
Split(new chae[] {' ','\n','\r','\t'},
StringSplitOptions.RemoveEmptyEntries),
new Converter<string, int>(int.Parse));
int j = 0;
x = a[j++]; dx = a[j++]; d = a[j++]; dd = a[j++];
t = a[j++]; dt = a[j++]; v = a[j++]; dv = a[j];
} // Doc
static public void XuLi(){
int b = Bcnn(dx,dt);
nx = b / dx; // so doan xanh trong 1 bo xanh tim
nt = b / dt; // so doan tim trong 1 bo xanh tim
int nxt = Min(x / nx, t / nt); // so bo xanh tim
nx = nxt * nx; // so doan xanh can chon
nt = nxt * nt; // so doan tim can chon
b = Bcnn(dd,dv);
nd = b / dd; // so doan do trong 1 bo do vang
nv = b / dv; // so doan vang trong 1 bo do vang
int ndv = Min(d / nd, v / nv);// so bo do vang
nd = ndv * nd; // so doan do can chon
nv = ndv * nv; // so doan vang can chon
} // XuLi
static public int Ucln(int a, int b){
int r;
while (b != 0) { r = a % b; a = b; b = r; }
return a;
}
static public int Bcnn(int a, int b)
{ return a*(b/Ucln(a, b));}
static public int Min(int a,int b): t vit
static public void Ghi(){
StreamWriter g = File.CreateText(gn);
g.WriteLine((nx*dx*nd*dd)); // dien tich
g.WriteLine(nx+" "+nd+" "+nt+" "+nv);//so doan moi loai
g.Close();
}
// Hien thi lai cac files input, output
static public void XemKetQua(): t vit
}// Xdtv1
} // SangTao2
Bi 1.9 Xanh tm vng 2
Cho 4 loi on thng sn cc mu xanh di dx, di dd, tm di dt v vng di dv. Cc on
thng cng mu th c cng chiu di v s lng khng hn ch. Hy chn ra khng qu N on thng ri
xp ni nhau theo chu vi thu c mt hnh ch nht c din tch ln nht vi cc cnh ln lt mang
cc mu theo chiu quay ca kim ng h l xanh, , tm, vng. D liu trong bi u l cc s nguyn
dng.

XDTV2.INP XDTV2.OUT D liu vo: tp vn bn XDTV2.INP

28

35
3 2 2 5

480
8 10 12 4
Dng th nht: s N > 0.
Dng th hai: bn s dx dd dt dv
D liu ra: tp vn bn XDTV2.OUT
Dng u tin: Din tch ca hnh ch nht xanh - -
tm - vng.
Dng th hai: 4 s cho bit s lng on thng cn
chn theo mi loi mu ghp c hnh ch nht din
tch max.

Kt qu trn cho bit cn chn 8 on xanh, 10 on , 12 on tm v 4 on vng ghp thnh
hnh ch nht c din tch max l 480.
Thut ton
Phng php: Tham.
Tng t nh bi Xanh tm vng 1, trc ht ta tnh cc b xanh - tm (nx,nt) v b - vng (nd, nv).
Tip n ta tnh xem khi ly i b xanh tm kt hp vi j b - vng th thu c hnh ch nht c
din tch max l bao nhiu. Lu rng i b xanh - tm s gm i(nx+nt) on thng. S on thng cn li
khi s l N i(nx+nt). S ny s to ra c j = (N i(nx+nt)) / (nd+nv) b - vng.
phc tp: O(n).
(* Pascal *)
(******************************************
Xanh Do Tim Vang 2
******************************************)
program xdtv2;
uses crt;
const
fn = 'xdtv2.inp'; gn = 'xdtv2.out'; bl = #32;
var
n: longint;
f,g: text;
x,d,t,v: longint;
dx,dd,dt,dv: longint;
nx,nt,nd,nv: longint;
smax,bmax: longint;
procedure Doc: T vit;
function Ucln(a,b: longint): T vit;
function Bcnn(a,b: longint): T vit;
function Min(a,b: longint): T vit;
(*---------------------------------------------------------
1 bo xanh - tim = (sx,st) = (so doan xanh, so doan tim)
sx = bcnn(dx,dt) div dx
st = bcnn(dx,dt) div dt
bxt = sx + st
--------------------------------------------------------*)
procedure XuLi;
var b: longint;
bxt, bdv: longint;
s: longint;
sx,st, sd, sv: longint;
begin
b := bcnn(dx,dt);

29
sx := b div dx;
st := b div dt;
bxt := sx + st;
b := Bcnn(dd,dv);
sd := b div dd;
sv := b div dv;
bdv := sd + sv;
smax := 0; bmax := 0;
for b := 1 to ((n - bdv) div bxt) do
begin
s := (b*sx*dx)*(((n b*bxt) div bdv)*sd*dd);
if (s > smax) then
begin bmax := b; smax := s; end;
end;
nx := bmax * sx; nt := bmax * st;
b := smax div (nx*dx); { Chieu dai canh Do ( = Vang) }
nd := b div dd; nv := b div dv;
end;
procedure Ghi: T vit;
BEGIN
Doc; XuLi; Ghi;
END.
// C#
using System;
using System.IO;
using System.Collections;
/*===============================================
Xanh Do Tim Vang 2
===============================================*/
namespace SangTao2 {
class Xdtv2 {
static int n;
static int dx, dd, dt, dv;
static int nx, nd, nt, nv; // Dap so: so luong moi loai
const string fn = "xdtv1.inp";
const string gn = "xdtv1.out";
static void Main(string[] args){
Doc(); XuLi(); Ghi();
XemKetQua(); Console.WriteLine("\n Fini");
Console.ReadLine();
}
static public void Doc(){
int[] a = Array.ConvertAll(File.ReadAllText(fn).
Split(new chae[] {' ','\n','\r','\t'},
StringSplitOptions.RemoveEmptyEntries),
new Converter<string, int>(int.Parse));
int j = 0;
n = a[j++]; dx = a[j++]; dd = a[j++];
dt = a[j++]; dv = a[j];
} // Doc
static public void XuLi() {
int b = Bcnn(dx,dt);
int sx = b / dx; // so luong doan xanh trg 1 bo XT
int st = b / dt; // so lg doan tim trg 1 bo X-T
int sxt = sx+st; // tg so doan xanh va tim trg bo XT

30
b = Bcnn(dd,dv);
int sd = b / dd, sv = b / dv; // do, vang
int sdv = sd + sv;// tg so doan do va vg trg bo DV
int smax = 0; // dt max
int bxtmax = 0; // so bo XT toi da
int bb = (n-sdv)/sxt; // can tren cua cac bo XT
for (b = 1; b <= bb; ++b) { // b - so bo XT
int s = (b*sx*dx)*(((n-b*sxt)/sdv)*sd*dd);// dt
if (s > smax) { bxtmax = b; smax = s; }
}
nx = bxtmax * sx; nt = bxtmax * st;
b = smax / (nx * dx); // chieu dai canh Do = Vang
nd = b/dd; nv = b/dv;
} // XuLi
static public int Ucln(int a, int b): T vit;
static public int Bcnn(int a, int b): T vit;
static public int Min(int a,int b): T vit;
static public void Ghi(): T vit;
static public void XemKetQua(): T vit;
}// Xdtv2
} // SangTao2
Bi 1.10 Ph on 2
Cho n on thng <a
i
, b
i
> vi cc im u a
i
v im cui b
i
l nhng s nguyn trong khong
1000..1000,
a
i
< b
i
v thuc mt trong 4 dng sau y:
[d,c] - on ng: cha im u d v im cui c,
(d,c] - on m tri: khng cha im u d, cha im cui c,
[d,c) - on m phi: cha im u d, khng cha im cui c,
(d,c) - on m: khng cha im u d v im cui c.
Hy ch ra t nht K on thng sao cho khi t chng trn trc s th c th ph kn on <x, y>
vi ta nguyn cho trc.


Kt qu trn cho bit t nht l 3 on 1, 2 v 6 s ph kn on (4,10).
Ch : Gia cc s v cc k t trong file input c th cha cc du cch.
Thut ton
Phng php: Tham
DOAN.INP DOAN.OUT D liu vo: tp vn bn DOAN.INP
Dng u tin: s t nhin 1 < N s 1000.
Dng th hai: on x y
T dng th ba lit k cc on, mi dng
c th cha nhiu on, mi on c ghi trn
trn mt dng.
D liu ra: tp vn bn DOAN.OUT
Dng u tin: s K, nu v nghim K=0.
Tip theo l K s t nhin biu th ch s ca
cc on thng ph kn on x y.

6
(4,10 )
(-2, 5)
[ 5 , 7] [6, 7)
[7, 8) (8,9)
(7 , 10 ]



3
1
2
6




31
ng dng thut ton ca bi Ph on 1 ta a cc on v cng mt dng ng bng cch chnh
li cc u m. C th l thm/bt im u m ca mi on mt lng c = 0.3 nh sau,
[d,c] gi nguyn
(d,c] [d + c, c],
[d,c) [d, c - c],
(d,c) [d + c, c - c].
Qui tc trn kh d hiu. Bn hy gii thch v sao chn c = 0.3 m khng chn c = 0.5?
Hai trng a v b th hin cc im u v cui mi on cn c khai bo kiu real (float).
Cc bin lin quan n cc trng ny trong th tc x l cng cn c khai bo theo cc kiu trn.
Ta c tt c cc on v ghi vo mng d[0..N], trong d[0] s cha on x, y.
Cch c cc on c t chc trn c s gi thit l cc on c vit ng c php. Mi ln ta
c mt k t ch t tp input. Nu (ch = () hoc (ch = [) th ta gp k t u on: ta tin hnh c mt
on. c mt on ta ln lt c s th nht, b qua du phy (,) ngn cch gia hai s ri c s
th hai. Th tc c mt on kt thc khi gp mt trong hai du ng ngoc l ] hoc ). Cn c vo cc
du m v ng ngoc u v cui mi on ta xc nh lng c cn thm hoc bt cho mi im u
hoc cui on, ng nhin cc im ny cn c biu din di dng s thc.
phc tp: N
2
.
Ch
Bn c th dng k thut ng dng chuyn trc s sang trc s "phng i" gp 3 ln. Khi cc
on tng ng s c chuyn nh sau:
[d,c] [3d - 1, 3c + 1],
(d,c] [3d + 1, 3c + 1],
[d,c) [3d - 1, 3c - 1],
(d,c) [3d + 1, 3c - 1].
Tc l gi li kiu nguyn v chn c = 1. Cch lm ny c n gin hn trong trng hp gii hn ca d v
c l nh.
(* Pascal *)
(*========================================
Phu doan 2
=========================================*)
program PhuDoan2;
uses crt;
const
mn = 2002; bl = #32; nl = #13#10;
fn = 'doan.inp'; gn = 'doan.out';
MoVuong = '['; DongVuong = ']'; MoTron = '('; DongTron = ')';
NgoacMo = [MoVuong, MoTron]; NgoacDong = [DongVuong, DongTron];
ChuSo = ['0'..'9']; CongTru = ['+','-']; eps = 0.3;
type
KieuDoan = record
a,b: real;
id: integer; { ch s on }
end;
md1 = array[0..mn] of KieuDoan;
mi1 = array[0..mn] of integer;
var n: integer; { n - so luong doan }
d: md1;
f,g: text;
t: mi1;
xy: KieuDoan;

32
ch: char;
k: integer; {dem so doan da doc}
Ngoac: char;
(* Doc 1 so nguyen tu input file *)
function DocSo: integer;
var s,dau: integer;
begin
s := 0; dau := 1;
while not (ch in (CongTru + ChuSo)) do read(f,ch);
if (ch in CongTru) then
begin
if (ch = '-') then dau := -1;
read(f,ch);
end;
while not (ch in ChuSo) do read(f,ch);
repeat
s := 10*s + ord(ch) - ord('0');
read(f,ch);
until not (ch in ChuSo);
DocSo := dau * s;
end;
procedure DocDoan;
begin
k := k + 1; d[k].id := k; Ngoac := ch; d[k].a := DocSo;
if (Ngoac = MoTron) then d[k].a := d[k].a + eps;
while (ch <> ',') do read(f,ch);
d[k].b := DocSo;
while not(ch in NgoacDong) do read(f,ch);
if (ch = DongTron) then d[k].b := d[k].b - eps;
end;
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f); readln(f,n); k := -1;
while (k < n) and (not eof(f)) do
begin
read(f,ch);
if (ch in NgoacMo) then DocDoan;
end;
close(f); xy.a := d[0].a; xy.b := d[0].b;
end;
procedure Qsort(l,r: integer): xem bi ph on 1;
function Tim(id,ic: integer; x: real): xem bi ph on 1;
procedure Ket(k: integer): xem bi ph on 1;
procedure XuLi: xem bi ph on 1;
BEGIN
Doc; Qsort(1,n); XuLi;
END.
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao2 {
class PhuDoan2 { // Cac doan dong mo
static public string fn = "Doan.inp";

33
static public string gn = "Doan.out";
static public string s; // du lieu vao
static public Doan[] d; // cac doan
static public int[] c; // luu cac doan ket qua
static public Doan xy;
static public int n = 0; // so luong doan
static public int si; // index cho s
static int m; // so luong doan phu
const float eps = 0.3f;
static void Main(string[] args) {
Doc(); QSortB(d, 0, n - 1);
m = XuLi(); Ghi(); XemKetQua();
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void XemKetQua(): t lm
static public void Doc() {
s = (File.ReadAllText(fn)).Trim();
si = 0; n = DocSo();
xy = DocDoan(0);
d = new Doan[n];
for (int i = 0; i < n; ++i) d[i] = DocDoan(i+1);
}
static public void Ghi(): t lm
static public int XuLi(): t lm
static public int Tim(int i, int j, float x): t lm
static public void QSortB(Doan[] d, int t, int p): t lm
// c on th i
static public Doan DocDoan(int i) {
Cach();
char mo = s[si++];
float a = DocSo();
if (mo == '(') a += eps;
float b = DocSo();
Cach();
char dong = s[si++];
if (dong == ')' b -= eps;
return new Doan(a, b, i);
}
// b qua cc du trng
static public void Cach() {
while (s[si]==' '||s[si]=='\n'
||s[si]=='\t'||s[si]=='\r') ++si;
}
static public void DenSo() {
while ((s[si]<'0'||s[si]>'9')&&(s[si]!='+')
&&(s[si]!='-')) ++si;
}
static public int DocSo(){
int m = 0, dau = 1;
DenSo();
if (s[si] == '+') ++si;
if (s[si] == '-') { ++si; dau = -1; }
do {
m = m * 10 + s[si++] - '0';
} while (s[si] >= '0' && s[si] <= '9');
return dau*m;

34
}
} // PhuDoan2
public struct Doan { // M t mt on
public float a, b;
public id;
public Doan(float x1, float x2, int z) // To on mi
{ a = x1; b = x2; id = z; }
} // Doan
} // SangTao2
Bi 1.11 on ri 2
Cho N on thng vi cc im u a
i
v im cui b
i
l nhng s nguyn trong
khong1000..1000, a
i
< b
i
. Lit k s lng ti a cc on thng ri nhau. Hai on c xem l ri
nhau nu chng khng c im chung. Cc on c dng nh trong bi Ph on 2.


Kt qu trn cho bit c ti a 5 on ri nhau l 1, 2, 7, 3 v 4.
Thut ton
Phng php: Tham.
Trc ht ta chnh li cc u h ging nh bi trc sau p dng thut ton ca bi on ri.
Cc im u v cui on v cc bin lin quan c khai bo kiu s thc.
phc tp: N.logN chi ph cho quick sort.
(* Pascal *)
(*========================================
liet ke toi da cac doan thang roi nhau
=========================================*)
program DoanRoi2;
uses crt;
T chc d liu: xem bi Ph on 2
function DocSo: xem bai Phu doan 2;
procedure DocDoan: xem bai Phu doan 2;
procedure Doc: xem bai Phu doan 2;
procedure Qsort(l,r: integer): xem bai Phu doan 2;
procedure XuLi : xem bai Doan roi 1;
procedure Ket: xem bai Doan roi 1 ;
BEGIN
Doc; Qsort(1,n);
XuLi; Ket;
END.
DOAN.INP DOAN.OUT D liu vo: tp vn bn DOAN.INP
Dng u tin: s t nhin N > 1.
T dng th hai: lit k cc on, mi dng
c th cha nhiu on, mi on c ghi trn
trn mt dng.
D liu ra: tp vn bn DOAN.OUT
Dng u tin: s K.
Tip theo l K s t nhin biu th ch s ca
cc on thng ri nhau.

8
( -2, 3) [3 , 5)
[8, 12] [13 ,15 )
(1 , 9 ) ( 2, 5 ]
[5 ,8 ) [7, 15]



5
1 2 7 3 4



35

// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao2 {
class DoanRoi2 { // Cac doan dong mo
T chc d liu: xem bi Ph on 2
static void Main(string[] args) {
Doc(); QSortB(d, 0, n - 1);
XuLi(); Ghi();
XemKetQua();
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void XemKetQua(): xem bai Phu doan 2
static public void Doc(): xem bai Phu doan 2
static public void Ghi(): xem bai Doan Roi 1
static public void XuLi(): xem bai Doan roi 1
// Sap tang cac doan theo dau phai (b)
static public void QSortB(Doan[] d, int t, int p): t lm
static public Doan DocDoan(int i): xem bai Phu doan 2
static public int DocSo(): xem bai Phu doan 2
} // DoanRoi2
public struct Doan: xem bai Phu doan 2
} // SangTao2
Bi 1.12 Ghp hnh ch nht
Cho N on thng cng chiu di d n v. Hy chn K on ghp thnh cnh ca hnh ch nht
c din tch ln nht.
Input: Hai s N v d, n > 4.
Output: Hin th trn mn hnh
- t: Tng s on cn chn t,
- a: S on t trn 1 chiu rng
- b: S on t trn 1 chiu di,
- s: Din tch max.
Th d,
Input: N = 23, d = 2.
Output: 22 5 6 120.
Thut ton
nh l Trong cc hnh ch nht cng chu vi th hnh vung c din tch ln nht.
Chng minh
Gi c l chu vi ca hnh ch nht, a l chiu rng, b l chiu di, b > a, d l lch gia chiu di b
v chiu rng a. Ta c, b = a + d v c = 2(a+a+d) = 4a + 2d, din tch s = a(a+d). Thay gi tr a = (c2d)/4
vo biu thc tnh din tch v rt gn ta thu c s = c
2
/16 d
2
/4 = (c
2
4d
2
)/16. Gi tr s t max khi v
ch khi d = 0, tc l khi a = b. Vy hnh ch nht c din tch ln nht l c
2
/16 chnh l hnh vung.
T nh l trn ta rt ra heuristics sau y: mun xy dng mt hnh ch nht c din tch ln nht
t mt chu vi c c nh vi cc cnh nguyn cho trc ta phi chn lch gia chiu di v chiu rng
nh nht c th c.
Khi tr: a = b = N div 4.

36
Xt cc trng hp s on cn tha r = N mod 4.
r = 0: b qua
r = 1: b qua
r = 2: thm chiu di 1 on, b := b + 1;
r = 3: thm chiu di 1 on, b := b + 1;
Tng qut: a = N div 4; b = a + (N mod 4) div 2;
Khi din tch s l: s = a*b*d*d.
Th d, N = 23, d = 2: a = 23 div 4 = 5; b = a + (N mod 4) div 2 = 5 + (3 div 2) = 5 + 1 = 6;
t = 2*(a+b) = 2*(5+6) = 22; s = a*b*d*d = 5*6*2*2 = 120.
phc tp: O(1).
(* Pascal *)
(*========================================
Chon t trong n doan de ghep duoc HCN
dien tich max
=======================================*)
program GhepChuNhat;
uses crt;
const bl = #32;
procedure ChuNhatMax(n,d: longint);
var a,b,t,s: longint;
begin
a := n div 4; b := a + ((n mod 4) div 2);
t := 2 * (a + b); { tong so doan }
s := a * b * d * d;
writeln(t,bl,a,bl,b,bl,s);
end;
BEGIN
ChuNhatMax(23,2);
END.
Kt qu d kin:
22 5 6 120
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao2 {
class GhepHCN {
static void Main(string[] args){
ChuNhatMax(23,2);
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void ChuNhatMax(int n, int d){
int a = n / 4;
int b = a + ((n % 4) / 2);
int t = 2 * (a + b);
int s = a * b * d * d;
Console.WriteLine(t + " " + a + " " + b + " " + s);
}
} // GhepHCN
} // SangTao2

37
Bi 1.13 Xanh
Cho x on thng mu xanh c chiu di bng nhau l dx n v v d on mu c chiu di
bng nhau l dd n v. Hy chn nx on xanh v nd on t trn chu vi ca hnh ch nht to thnh
mt ng vin an mu (cc mu xen k nhau) v din tch ca hnh l ln nht.
Input: Bn s x, dx, d v dd, x > 2, d > 2.
Output: Hin th trn mn hnh
- nx: S on xanh c chn,
- nd: S on c chn,
- s: Din tch max.

* Th d 1
input: (x, dx, d, dd) = (5, 2, 7, 2)
output: (nx, nd, s) = (5, 5, 24)
* Th d 2
input: (x, dx, d, dd) = (6, 2, 7, 3)
output: (nx, nd, s) = (6, 6, 56)
* Th d 3
input: (x, dx, d, dd) = (6, 2, 7, 2)
output: (nx, nd, s) = (6, 6, 36)
* Th d 4
input: (x, dx, d, dd) = (7, 2, 7, 3)
output: (nx, nd, s) = (6, 6, 56)


Hnh ch nht
c cnh an mu
xanh - v t
din tch max




















x = 11, dx = 1,
d = 10, dd = 2.
nx = 10, nd = 10,
s = 7 8 = 56.


Thut ton
D thy l thu c hnh c ng vin an mu th cn chn s on xanh nx v s on nd
nh nhau, tc l chn nx = nd = min(x, d). Khi chu vi ca hnh s gm t = nx + nd = 2nx = 2nd on, v
do t l mt s chn. Do t chn nn (t mod 4) s bng 0 hoc 2.
K hiu a l s on (tnh c xanh v ) cn t trn mt chiu rng, b l s on (tnh c xanh v
) cn t trn mt chiu di ca hnh. Xt hai trng hp dx = dd v dx dd.
1. Trng hp th nht: dx = dd. Ta c, a = b = t div 4. Nu (t mod 4 = 2). Ta thm vo chu vi mt
cp xanh na. Vy ta cn chn:
- nx = min(x,d) on xanh,
- nd = nx on ,
- Din tch max: s = a * b * dx * dx vi
a = t div 4 l s on t trn 1 chiu rng,
b = a + ((t mod 4) div 2) l s on t trn 1 chiu di.
2. Trng hp th hai: dx dd. Ta thy, m bo tnh an mu th a v b phi c cng tnh chn
l. T thy rng khi (t mod 4 = 2) ta phi b qua s d, v nu thm cho chiu di b 1 on na th tnh
chn l ca a v b s khc nhau. rng khi a v b cng chn th hnh nhn c s vung v mi cnh
cha ng z = a div 2 on xanh v z on . Khi din tch c th tnh theo cng thc: s = sqr(z * (dx +
dd)). Nu a v b cng l th s lng on xanh v s lng on trong mt cnh s hn km nhau 1
n v. Nu cnh ny nhiu xanh hn th cnh k vi cnh s nhiu hn xanh. Khi din tch s
c tnh theo cng thc
s = (z * dx + (z+1) *dd) * (z * dd + (z+1) * dx) = (z * dx + z * dd + dd) * (z * dd + z * dx + dx)
= (z * (dx + dd) + dd) * (z * (dx + dd) + dx) = (k + dd) * (k + dx)
vi z = a div 2, k = (a div 2)*(dx + dd).

38
Kt qu l cn chn:
nx = min(x,d). Chu vi 2*nx phi l bi ca 4, tc l nx phi chn. Nu nx l th t li nx := nx 1.
nd = nx;
tng cng t = nx + nd on, trong
S on t trn 1 chiu rng: a = t div 4,
S on t trn 1 chiu di: b = a,
- Din tch max: (k+dd) * (k+dx), k = (a div 2)*(dx+dd).
phc tp: O(1).
(* Pascal *)
program XanhDo;
uses crt;
const bl = #32;
function Min(a,b: longint): t vit
procedure XD(x,dx,d,dd: longint);
var a,b,nx,nd,k,t,s: longint;
begin
if (dx = dd) then
begin
nx := Min(x,d); nd := nx; t := nx + nd;
a := t div 4;
b := a + ((t mod 4) div 2); s := a * b * dx * dx
end
else { dx <> dd }
begin
nx := Min(x,d);
if (nx mod 2 > 0) then nx := nx - 1;
nd := nx; t := nx + nd; a := t div 4; b := a;
k := (a div 2) * (dx + dd);
if (Odd(a)) then s := (k + dx) * (k + dd)
else s = k*k;
end;
writeln(nx,bl,nd,bl,s);
end;
BEGIN
XD(7, 2, 7, 3);
END.
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao2 {
class XanhDo {
static void Main(string[] args){
XD(11, 1, 9, 2);
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void XD(int x, int dx, int d, int dd){
int nx = Min(x,d); // so luong doan xanh can chon
int nd; // so luong doan do can chon
int t; // tong so: nx + nd
int a,b; // chieu rong, dai tinh theo so doan

39
int s; // dien tich max
if (dx == dd){
nd = nx; t = nx + nd;
a = t / 4; b = a+((t % 4)/2);
s = a*b*dx*dx;
} else {
if (nx % 2 > 0) --nx;
nd = nx; t = nx+nd; b = a = t / 4;
int k = (a/2)*(dx+dd);
s = (a % 2 == 0) ? k * k : (k+dx)*(k+dd);
}
Console.WriteLine("\n " + nx + " " + nd + " " + s);
}
static public int Min(int a,int b): t vit
} // XanhDo
} // SangTao2
Bi 1.14 Xp on
Cho N on thng trn trc s vi cc im u x
i
l nhng s nguyn trong khong 1000..1000
v di d
i
l nhng s nguyn dng trong khong 1..1000, i = 1..N. Tnh tng chiu di cc on
ph trn trc s.

DOAN.INP OUTPUT D liu vo: tp vn bn DOAN.INP
Dng u tin: s t nhin 1 < N s 1000.
Dng th i trong N dng tip theo, mi dng cha hai
s nguyn a
i
d
i
cch nhau qua du cch, biu th im u
v chiu di ca on th i, i = 1..N.
D liu ra: hin th trn mn hnh tng chiu di t cc
on ph trn trc s.


5
3 5
-11 3
-20 4
-12 8
2 5

28


Thut ton
Phng php: tham.
Sp tng cc on theo im u x.
Ta dng k hiu [x,y] biu din cho on thng c im u x v im cui y, x:d biu din cho on
thng c im u x v chiu di d. Ta nh ngha mt ln l on to bi cc on giao nhau lin tip. Hai
on [a,b] v [c,d] c gi l giao nhau nu chng c im chung. iu kin ny c ngha im u ca
on ny nm trong on th hai, tc l a s c s b hoc c s a s d. Do cc on c sp tng theo im
u x nn hai on x
i
:d
i
v x
j
:d
j
s giao nhau khi v ch khi x
j
s x
i
+ d
i
. rng x
i
+ d
i
l im cui ca
oan i. Nu hai on i v j giao nhau th ta hp chng thnh mt on [a,b] vi a = x
i
v b = max(x
i
+ d
i
,
x
j
+d
j
). Kt hp cc on giao nhau lin tip n mc ti a ta thu c mt ln gi l ln ti i [a,b] c
chiu di b a.
Ta khi tr ln [a, b] bng on u tin x
1
:d
1
, c th l a := x
1
, b := x
1
+d
1
(= a + d
1
).
Vi mi on i := 2..N ta xt:
- Nu on i giao vi ln [a,b], tc l x
i
s b th ta hp on i vi ln to ra ln mi [a,b]
bng cch chnh b := max(b, x
i
+ d
i
) .
- Nu on i khng giao vi ln [a,b] th ta cng tch ly chiu di ca ln [a,b] hin c vo
bin tng t ri sinh ra ln mi t on i.
t := t + (b a);

40
a := x
i
; b := a + d
i
;
Sau khi kt thc duyt cc on ta cng nt ln cui cng vo tng t bng thao tc t := t + (b a).
phc tp: O(N.logN) chi ph cho sp xp Qsort.
(* Pascal *)
(**************************************
Xep doan
***************************************)
program XepDoan;
uses crt;
const
bl = #32; fn = 'DOAN.INP'; mn = 1001;
type KieuDoan = record x: integer; d: integer; end;
md1 = array[0..mn] of KieuDoan;
var c: md1; { chua cac doan }
n: integer;
f: text;
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f); readln(f,n);
for i := 1 to n do readln(f,c[i].x,c[i].d);
close(f);
end;
(*---------------------------------
Sap tang cac doan theo
diem dau x
---------------------------------*)
procedure Qsort(t,p: integer): t vit;
function max(a,b: integer): t vit
function Tong: longint;
var t: longint; { tong do dai }
a, b: integer; { lan [a, b] }
i: integer;
begin
t := 0;
a := c[1].x; b := a + c[1].d; { Khoi tri lan }
for i := 2 to n do
if (c[i].x <= b) then b := max(b,c[i].x + c[i].d)
else
begin
t := t + (b - a);
a := c[i].x; b := a + c[i].d;
end;
Tong := t + (b - a);
end;
BEGIN
Doc; Qsort(1,n); writeln(Tong);
END.
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao2 {

41
class XepDoan {
const string fn = "doan.inp";
const string gn = "doan.out";
static public int n; // so luong doan
static public Doan[] c; // cac doan
static void Main(string[] args) {
Doc(); QSort(0, n - 1);
Console.WriteLine("\n \n Dap so: "+CoverSum());
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void Doc(): t vit
static public int CoverSum() {
int a = c[0].x, b = a + c[0].d, t = 0;
for (int i = 1; i < n; ++i)
if (c[i].x <= b) b = Max(b, c[i].x + c[i].d);
else { t += (b-a); a = c[i].x; b = a+c[i].d; }
return t + (b - a);
}
static public int Max(int a, int b): t vit
// Sap cac doan tang theo diem dau x
static public void QSort(int s, int e): t vit
} // XepDoan
public struct Doan: t vit
} // SangTao2
Bi 1.15 Cc hnh ch nht
ACM
Trn mt phng ta cho N hnh ch nht (HCN) c din tch khc 0 v c cc cnh song song vi
cc trc ta . Mi HCN c m t bng b bn s nguyn (x
1
,y
1
) v (x
2
,y
2
) biu th ta nguyn ca
hai nh i din.
Yu cu: xc nh din tch phn mt phng b cc HCN ph.

HCN.INP HCN.OUT D liu vo: tp vn bn HCN.INP
Dng u tin: s t nhin 1 < N s 1000.
Dng th i trong N dng tip theo, mi dng cha 4
s nguyn x
1
, y
1
, x
2
, y
2
cch nhau qua du cch.
D liu ra: tp vn bn HCN.OUT cha tng n v
din tch trn mt phng b cc HCN ph.


5
0 0 2 4
1 2 4 6
5 3 3 7
4 1 6 5
7 3 9 0

35

Thut ton
Phng php: Tham.

y
2
A B



42
1. c d liu v chnh li cc ta sao cho
x1 s x2 v y1 s y2. iu ny c ngha l ta qui c mi HCN
ABCD u c xc nh qua 2 nh i din D (nh Ty-Nam)
v B (nh ng-Bc): D(x1, y1), B(x2, y2).
Khi c d liu ta ng thi lc bt cc gi tr y trng
lp v sp cc gi tr y
1
v y
2
theo chiu tng ghi vo mt
mng y[1..m]. Nh vy, gi tr ln nht ca m l 2n. Ta gi phn
mt phng gii hn bi hai ng thng song song vi trc honh v ct trc tung ti im y[i] v y[i+1] l
bng i. Ta c m1 bng m s t 1 n m1. Bng u tin c m s 1 nm gia hai ng y[1] v y[2],
bng cui cng c m s m1 nm gia hai ng y[m1] v y[m]. Nhim v cn li l tnh din tch b
ph trn mi bng. Tng s din tch b ph ca cc bng s l p s cho bi ton.
2. Ta li sp cc HCN theo chiu tng ca ta x1.
3. Vi mi HCN h(x1, y1, x2, y2) ta xt cc bng i trong khong t y1 n y2. Vi bng i gi s ta
bit phn b cc HCN 1..(h1) ph trn bng ny. Ta k hiu s[i] v e[i] l gii hn honh tri v phi
ca phn ang b ph trn bng i. Din tch hin b ph trn bng i s l: (y[i+1]y[i])*(e[i] s[i]), trong
y[i+1] y[i] l chiu rng ca bng i. Ta cn chnh li phn b ph trong bng i khi xt thm HCN h(x1, y1,
x2, y2). D thy, nu x1 nm gia s[i] v e[i] th ta cn chnh li e[i] theo cng thc e[i] := max(e[i], x2).
Ngc li, nu x1 > e[i] th ta kt thc ln (s[i],e[i]) ny nh sau: Tnh din tch ln ny v a vo bin
tch ly din tch dt sau t li cn s[i] := x1; e[i] := x2.
Do cc honh y1 v y2 c sp tng nn ta c th gi th tc tm kim nh phn BnSearch
xc nh bng cha y1.
phc tp: Cc thut ton sp xp v chn i hi ti a N
2
, Th tc x l xt mi HCN 1 ln v
duyt 2n bng. Tng hp: N
2
.
(* Pascal *)
(**********************************************
Cac hinh chu nhat

*********************************************)
program HinhChuNhat;
uses crt;
const mn = 2001; fn = 'HCN.INP'; gn = 'HCN.OUT';
bl = #32; nl = #13#10;
type CN = record
x1, y1: integer;
x2, y2: integer;
end;
mcn1 = array[0..mn] of CN;
mi1 = array[0..mn] of integer;
var
n,m: integer; { n - so HCN, m - so lan }
h: mcn1; { cac HCN }
y: mi1; { ranh gioi cac lan }
s, e: mi1; { Cac diem dau va cuoi cua bang }
f,g: text;
dt: Longint;
function Max(a,b: integer): t vit
(*-----------------------------
Hon i tr a s b
------------------------------*)
procedure Chinh(var a,b: integer);
var c: integer;
begin
if (a > b) then begin c := a; a := b; b := c; end;

y
1

D C
x
1
x
2

43
end;
(*------------------------------------
Tim nhi phan v trong y[1..m]
-------------------------------------*)
function BinSearch(v: integer): integer;
var d,c,t: integer;
begin
d := 1 ; c := m;
while (d < c) do
begin
t := (d + c) div 2;
if (y[t] < v) then d := t + 1
else c := t;
end;
BinSearch := d;
end;
(*-----------------------------
Xen them v vao day
da sap tang y[1..m]
------------------------------*)
procedure Insert(v: integer);
var d: integer;
begin
if (m = 0) then { danh sach rong }
begin m := m + 1; y[m] := v; exit; end;
d := BnSearch(v);
if (y[d] = v) then exit; { da co trong danh sach }
if (y[d] < v) then begin m := m + 1; y[m] := v; exit; end;
move(y[d], y[d+1],sizeof(integer)*(m-d+1));
y[d] := v; m := m + 1;
end;
(*-------------------------------
Doc du lieu va sap theo Y
luoc bot cac Y bang nhau
------------------------------*)
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f); readln(f,n); m := 0;
for i := 1 to n do
begin
readln(f,h[i].x1,h[i].y1,h[i].x2,h[i].y2);
Chinh(h[i].x1, h[i].x2); Chinh(h[i].y1, h[i].y2);
insert(h[i].y1); insert(h[i].y2);
end;
close(f);
end;
procedure SortByX1(d,c: integer);
var i,j,m: integer;
v: CN;
begin
i := d; j := c;
m := h[(i+j) div 2].x1;
while (i <= j) do
begin
while (h[i].x1 < m) do i := i + 1;
while (m < h[j].x1) do j := j - 1;

44
if (i <= j) then
begin
v := h[i]; h[i] := h[j]; h[j] := v;
i := i + 1; j := j - 1;
end;
end;
if (d < j) then SortByX1(d,j);
if (i < c) then SortByX1(i,c);
end;
(*----------------------------------
Xet HCN d, tinh tung phan
phu trong moi lan
------------------------------------*)
procedure Hinh(x1, x2, y1, y2: integer);
var i: integer;
begin
{ Tim xuat hien cua y1 trong cac lan }
i := BinSearch(y1);
while (y[i] < y2) do
begin
if (x1 <= e[i]) then
e[i] := Max(e[i], x2)
else
begin
dt := dt + (e[i] - s[i]) * (y[i+1] - y[i]);
s[i] := x1; e[i] := x2;
end;
i := i + 1;
end;
end;
procedure XuLi;
var d: integer;
begin
{ Khoi tri }
dt := 0;
for d := 1 to m-1 do
begin s[d] := -maxint; e[d] := s[d]; end;
{ Duyet cac HCN }
for d := 1 to n do
Hinh(h[d].x1, h[d].x2, h[d].y1, h[d].y2);
{ Tong hop ket qua }
for d := 1 to m-1 do
dt := dt + (e[d] - s[d]) * (y[d+1] - y[d]);
end;
procedure Ghi;
begin
assign(g,gn); rewrite(g); writeln(g,dt); close(g)
end;
BEGIN
Doc; SortByX1(1,n); XuLi; Ghi;
END.
// C#
using System;
using System.IO;
using System.Collections;

45
namespace SangTao2 {
class Hcn {
const string fn = "hcn.inp";
const string gn = "hcn.out";
static public int n,m; // n - so luong HCN; m - so bang
static public HCN[] c;
static public int dt; // tong dien tich
static public int[] y;
static void Main(string[] args) {
Doc(); QSortByx1(0, n - 1);
XuLi(); Ghi(); XemKetQua();
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void Ghi()
{ File.WriteAllText(gn,dt.ToString()); }
static public void XemKetQua(): t vit
static public void XuLi(){
dt = 0; // tong dien tich
int[] s = new int[m]; // diem dau cac bang
int [] e = new int [m]; // diem cuoi cac bang
for (int i = 0; i < m; ++i)
s[i] = e[i] = int.MinValue;
// Duyet cac HCN
for (int i = 0; i < n; ++i) { // xu li HCN i
int sj = BinSearch(c[i].y1);
int ej = BinSearch(c[i].y2);
for (int j = sj; j < ej; ++j){ // xet bang j
if (c[i].x1 <= e[j]) e[j] = Max(e[j], c[i].x2);
else {
dt += (e[j] - s[j])*(y[j+1]-y[j]);
s[j] = c[i].x1; e[j] = c[i].x2;
}
}
}
// Tong hop ket qua
int m1 = m - 1;
for (int j = 0; j < m1; ++j)
dt += (e[j] - s[j])*(y[j+1]-y[j]);
}
static public int Max(int a, int b): t vit
static public void Doc() {
int[] v =
Array.ConvertAll(((File.ReadAllText(fn))).Split(
new chae[] { ' ', '\t', '\r', '\n' },
StringSplitOptions.RemoveEmptyEntries),
new Converter<string, int>(int.Parse));
int j = 0; n = v[j];
c = new HCN[n];
int dx, dy, bx, by, t;
m = 0;
y = new int[2*n];
for (int i = 0; i < n; ++i, j += 4) {
dx = v[j + 1]; dy = v[j + 2];
bx = v[j + 3]; by = v[j + 4];
if (dx > bx) { t = dx; dx = bx; bx = t; }
if (dy > by) { t = dy; dy = by; by = t; }

46
c[i] = new HCN(dx, dy, bx, by);
Insert(dy); Insert(by);
}
}
// Tim nhi phan gia tri v trong y[0..m-1]
static public int BinSearch(int v) {
int left = 0, right = m-1, midle;
while (left < right) {
midle = (left + right)/2;
if (y[midle] < v) left = midle + 1;
else right = midle;
}
return left;
}
// Xen toa do v vao danh sach cac lan y
static public void Insert(int v) {
if (m == 0) { y[m++] = v; return; }
int i = BinSearch(v);
if (y[i] == v) return;
if (y[i] < v) { y[m++] = v; return; }
Array.Copy(y, i, y, i + 1, m - i);
y[i] = v; ++m;
}
// Sap cac HCN tang theo x1
static public void QSortByx1(int s, int e) {
int i = s, j = e, m = c[(i + j) / 2].x1;
HCN t;
while (i <= j) {
while (c[i].x1 < m) ++i;
while (c[j].x1 > m) --j;
if (i <= j) {
t = c[i]; c[i] = c[j]; c[j] = t;
++i; --j;
}
}
if (s < j) QSortByx1(s, j);
if (i < e) QSortByx1(i, e);
}
} // Hcn
public struct HCN {
public int x1,y1,x2,y2;
public HCN(int dx, int dy, int bx, int by)
{ x1 = dx; y1 = dy; x2 = bx; y2 = by; }
}
} // SangTao2
Bi 1.16 Cc tam gic vung cn
ACM
Trn mt phng ta cho N tam gic vung cn, hai cnh gc vung song song vi hai trc ta
, cnh huyn nm bn phi tam gic. C th l nu k hiu tam gic l ABC th ta qui nh nh A l
nh gc vung, cnh gc vung AB song song vi trc honh ox, cnh gc vung AC song song vi trc
tung oy, AB = AC = d. Mi tam gic c m t bng b ba s nguyn x, y, d trong (x,y) l ta
nguyn ca nh A, d l chiu di cnh gc vung.
TAMGIAC.INP TAMGIAC.OUT

47













Yu cu: Tnh din tch do cc tam gic ph trn mt phng ta .

D liu vo: text file TAMGIAC.INP
Dng u tin: s t nhin N trong khong 2 .. 1000.
N dng tip theo: mi dng 3 s x y d cch nhau qua du cch, x v y bin thin trong khong
1000..1000, d trong khong 1..1000.
D liu ra: text file TAMGIAC.OUT cha mt s thc duy nht S l din tch b cc tam gic ph
trn mt phng ta .
Thut ton
Tng t nh bi Cc Hnh ch nht. Vi mi tam gic (x,
y, d) ta to ra hai ng song song vi trc honh v ct trc tung
ti cc im y v y+d, c th l mt ng cha cnh y v mt
ng i qua nh ca tam gic. Cc ng thng ny s to ra cc
bng. Vi mi tam gic (TG) ta cng xt tng t nh HCN, ngha
l xt cc bng cha trong TG . Bin din tch dt c khai bo
kiu float v cc hnh trong bng j s l hnh thang c y ln l
e[j]s[j], y nh bng y ln h, h l chiu cao: h = y[j+1]y[j]
= rng ca bng. Khi chuyn t bng j ln bng j+1 ta phi
chnh li u phi x2 ca cnh y TG thnh x2 h v TG lc ny s ngn li. Khi tnh phn giao nhau ta
cn phi tr i din tch ca TG nm ngoi phn giao . Hnh v cho ta thy khi xt tam gic XYV v
bng gii hn trong 2 ng thng TM v SE, th ln (S, E) s c m rng thnh ln (S, V). Din tch
trc ca ln SE chnh l din tch hnh thang vung TMES, nay ln (S,V) c din tch ca hnh thang
vung TRVS. Nh vy ta tnh di ra phn din tch tam gic MPQ. D dng xc nh c din tch z
ca tam gic vung cn ny: t k = MP = PQ, ta c z = k
2
/2.Ta xc nh k nh sau. k = MP = TP TM =
SXTM = x(e[j]h), trong h l chiu rng ca bng j ang xt, h = y[j+1]y[j], e[j] l im cui ca
ln ang xt, x l honh ca nh gc vung trong tam gic XYV ang xt.
phc tp: N
2
.
(* Pascal *)
(**********************************************
Cac tam giac vuong can
*********************************************)
program TamGiacVuongCan;
uses crt;
const mn = 2001; bl = #32; nl = #13#10;
5
6 0 3
1 0 3
2 1 3
4 1 2
4 5 2
16.50



y C


A B
o x



T
M
S
Y
X
V E
R P
Q

48
fn = 'TamGiac.inp'; gn = 'TamGiac.out';
type TG = record
x,y: integer;
d: integer;
end;
mtg1 = array[0..mn] of TG;
mi1 = array[0..mn] of integer;
mr1 = array[0..mn] of real;
var
n,m: integer; { n - so tam giac }
y: mi1; { m - so diem y, max(m) = 2n }
t: mtg1;
f,g: text;
dt: real; // tong dien tich
(*--------------------------------------------
To chuc du lieu cho Bang i
s[i], e[i] - can trai va phai cua Bang
----------------------------------------------*)
s, e: mi1;
function Max(a,b: integer): t vit
(*-----------------------------
Xen them v vao day
da sap tang y[1..m]
------------------------------*)
procedure Insert(v: integer); t vit
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f); readln(f,n);
m := 0;
for i := 1 to n do
begin
readln(f,t[i].x,t[i].y,t[i].d);
Insert(t[i].y); Insert(t[i].y + t[i].d);
end;
close(f);
end;
{ Sap cac TG tang theo x }
procedure SortByX(d,c: integer); t vit
{ Tim nhi phan v trong y[1..m] }
function BinSearch(v: integer): integer; t vit
(*---------------------------------------
Xet hinh Tam giac h: tinh cac o
hinh h phu tren cac Bang
--------------------------------------*)
procedure Hinh(x1,y1,d: integer);
var i,y2,x2,h,k: integer;
begin
{ Tim xuat hien cua toa do y1 trong cac lan }
i := BinSearch(y1);
x2 := x1 + d; y2 := y1 + d;
while (y[i] < y2) do
begin
h := y[i + 1] - y[i];
if (x1 <= e[i]) then
begin
k := x1 - (e[i] - h); e[i] := Max(e[i], x2);

49
if (k > 0) then dt := dt - (real(k * k) / 2);
end
else
begin
if (e[i] > s[i]) then
dt := dt + h * (2 * (e[i] - s[i]) - h) / 2;
s[i] := x1; e[i] := x2;
end;
i := i + 1; x2 := x2 - h;
end;
end;
procedure XuLi;
var i, h: integer;
begin
for i := 1 to m do
begin s[i] := -maxint; e[i] := s[i]; end;
dt := 0.0;
{ Duyet cac TG }
for i := 1 to n do Hinh(t[i].x,t[i].y,t[i].d);
{ Tong hop ket qua }
for i := 1 to m-1 do
begin
h := y[i + 1] - y[i];
if (e[i] > s[i]) then
dt := dt + h * (2 * (e[i] - s[i]) - h) / 2;
end;
end;
procedure Ghi;
begin
assign(g,gn); rewrite(g); writeln(g,dt:0:2); close(g)
end;
BEGIN
Doc; SortByX(1,n); XuLi; Ghi;
END.
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao2 {
class TamGiac {
const string fn = "TamGiac.inp";
const string gn = "TamGiac.out";
static public int n, m; // n - so luong HCN; m - so bang
static public TG[] c;
static public float dt; // tong dien tich
static public int[] y;
static void Main(string[] args){
Doc(); QSortByx1(0, n - 1); XuLi();
Ghi(); XemKetQua();
Console.WriteLine("\n Fini "); Console.ReadLine();
}
static public void Ghi(): t vit
static public void XemKetQua(): t vit
static public void XuLi() {
dt = 0F;

50
int[] s = new int[m];
int[] e = new int[m];
for (int i = 0; i < m; ++i)
s[i] = e[i] = int.MinValue;
// Duyet cac TG c[i]
for (int i = 0; i < n; ++i) {
int x2 = c[i].x1+c[i].d; // dau phai cua canh day
int sj = BinSearch(c[i].y1);
int ej = BinSearch(c[i].y1 + c[i].d);
for (int j = sj; j < ej; ++j) {
// xet bang j
int h = y[j + 1] - y[j]; // do rong cua bang j
if (c[i].x1 <= e[j]) {
int k = c[i].x1 - (e[j] - h);
if (k > 0) dt -= (float)(k * k) / 2;
e[j] = Max(e[j], x2);
}
else {
if (e[j] > s[j])
dt += (float)(2*(e[j]-s[j])-h)*h/2;
s[j] = c[i].x1; e[j] = x2;
}
x2 -= h;
} // xong bang j
} // xong TG i
// Tong hop ket qua
int m1 = m - 1;
for (int j = 0; j < m1; ++j) {
int h = y[j+1]-y[j]; // do rong cua bang
if (e[j] > s[j])
dt += (float)(2*(e[j]-s[j])-h)* h/2;
}
static public int Max(int a, int b): t vit
static public void Doc() {
int[] v =
Array.ConvertAll(((File.ReadAllText(fn))).Split(
new char[] { ' ', '\t', '\r', '\n' },
StringSplitOptions.RemoveEmptyEntries),
new Converter<string, int>(int.Parse));
int j = 0; n = v[j];
c = new TG[n];
m = 0;
y = new int[2 * n];
for (int i = 0; i < n; ++i, j += 3) {
Insert(v[j + 2]); Insert(v[j + 2] + v[j + 3]);
c[i] = new TG(v[j + 1], v[j + 2], v[j + 3]);
}
}
// Tim nhi phan gia tri v trong y[0..m-1]
static public int BinSearch(int v): t vit
// Xen toa do v vao danh sach cac lan y
static public void Insert(int v): t vit
// Sap cac TG tang theo x1
static public void QSortByx1(int s, int e): t vit
} // TamGiac
public struct TG {
public int x1, y1, d;

51
public TG(int dx, int dy, int dd)
{ x1 = dx; y1 = dy; d = dd; }
}
} // SangTao2


52
Chng 2
Cc hm Next

Trong hu ht cc bi ca Chng, khi trnh by tham bin kiu mng trong cc hm v th tc ta
gi thit l cc kiu ny c khai bo trc. Th d, kiu mng nguyn mt chiu c khai bo nh
sau:
(* Pascal *) type mi1 = array[0..MN] of integer;
trong MN l hng s ln cho kch thc mi bi ton, th d
const MN = 2000;
Trong C# mng c khai bo trc tip hoc thng qua class, th d,
int [] a = new int [2000];
Class Array { };
Ty theo bi ton v ngn ng lp trnh chn, ta c th hoc khng s dng phn t u tin v
cui cng ca mng. Nh vy, mng x gm n phn t s c k hiu l x[1..n] trong Pascal hoc x[0..n1]
trong C#. Trong Pascal khai bo tham bin kiu var (truyn theo bin hay a ch) cho mng th th tc s
c gi nhanh hn, trong C# cc mng c ngm nh l truyn theo bin / a ch.
Bi 2.1 S st sau cng cao
Chiu di ca mt s t nhin l s ch s ca s . cao ca mt s t nhin l tng cc ch s
ca s . Cho s t nhin x ghi trong h m b, c chiu di N. Tm s t nhin y st sau x c cng chiu
di, cng cao v cng h m vi x.

D liu vo: tp vn bn DOCAO.INP
Dng u tin: hai s t nhin b v N cch nhau qua
du cch, 2 s b s 100, 2 s N s 1000.
Dng th hai: s x vi cc ch s ghi cch nhau qua
du cch.

D liu ra: tp vn bn DOCAO.OUT
Dng u tin: ghi 1 nu c nghim, 0: nu v nghim.
Dng th hai: s y vi cc ch s ghi cch nhau qua du cch.
Thut ton
cao ca s x s khng i nu ta ng thi tng v gim hai ch s ca x cng mt n v. Ta
duyt ln lt cc ch s ca x t phi qua tri, trc ht tm ch s x
j
> 0 u tin c th gim 1 n
v. Tip n ta duyt tip t j1 qua tri tm mt ch s x
i
< (b1) u tn sau j c th tng thm 1 n
DOCAO.INP DOCAO.OUT

10 5
2 3 9 9 0


1
2 4 0 8 9

53
v. Nu khng tm c x
j
hoc x
i
th x khng c s st sau. Nu tm c ng thi hai ch s x
j
v x
i
nh
trn th ta sa x nh sau:
- Gim x
j
1 n v,
- Tng thm x
i
1 n v,
- Lt li on x[i+1..n].
Vi th d x[1..5] = (2,3,9,9,0) trong h m thp phn (b = 10) ta tm c j = 4, x[j] = 9, i = 2, x[i]
= 3. Sau khi gim x[4] v tng x[2] 1 n v ta thu c x[1..5] = (2,4,9,8,0). S ny cn ln, nu lt li
on x[3..5] s thu c x[1..5] = (2,4,0,8,9). y l s cn tm.
V sao li lm nh vy? Gii thch iu ny kh d nu rng x[j+1..n] cha ton 0 (ch s nh
nht trong h m b) v x[i+1..j1] cha ton (b1) (ch s ln nht trong h m b). T suy ra rng
on x[i+1..n] c sp tng. Lt li on ta s thu c dy cc ch s gim dn. V x[i] c thm
1 n v nn n ln hn s ban u. Khi lt li ta s thu c s st sau s ban u.
Hm Next di y bin i trc tip x[1..n] thu c s st sau. Ta s dng phn t x[0] = b
lm gii hn cho qu trnh duyt ngc. Phn t x[0] ny c gi l lnh canh. N c nhim v lm cho
vng lp dng mt cch t nhin m khng cn phi kim tra gii hn ch s ca mng (rang check).
phc tp: c N, do mi ch s ca x c thm v x l khng qu 2 ln.
(* Pascal *)
function Next(var x: mi1; n,b: integer): Boolean;
var i,j,t,b1: integer;
begin
Next := FALSE;
x[0] := b; j := n;
while (x[j] = 0) do j := j - 1;
if (j = 0) then exit; { ko co so sat sau }
i := j - 1; b1 := b - 1 ;
while (x[i] = b1) do i := i - 1;
if (i = 0) then exit; { Ko co so sat sau }
x[j] := x[j] - 1; x[i] := x[i] + 1;
i := i + 1; j := n;
{ Lat doan x[i..n] }
while (i < j) do
begin
t := x[i]; x[i] := x[j]; x[j] := t;
i := i + 1; j := j - 1;
end;
Next := TRUE;
end;
// C#
static bool Next(int[] x, int n, int b) {
int i, j , b1 = b - 1;
for (j = n - 1; j >= 0; --j)
if (x[j] > 0) break;
if (j < 0) return false;
for (i = j - 1; i >= 0; --i)
if (x[i] < b1) break;
if (i < 0) return false;
--x[j]; ++x[i];
++i; j = n - 1;
int t;
while (i < j) {
t = x[i]; x[i] = x[j]; x[j] = t;

54
++i; --j;
}
return true;
}
Bi 2.2 S st sau cng ch s
Cho s t nhin x chiu di N. Hy i ch cc ch s ca x thu c s y st sau s x.

NXT.INP NXT.OUT
D liu vo: tp vn bn NXT.INP
Dng u tin: s t nhin N, 2 s N s 1000.
Dng th hai: s x
D liu ra: tp vn bn NXT.OUT
Dng u tin: ghi 1 nu c nghim, 0: nu v
nghim. Dng th hai: s y.

6
239521


1
251239
Thut ton
Trc ht rng mun thu c s st sau ca x th ta phi sa cc ch s hng thp nht c
th ca x, do thut ton s duyt cc ch s ca x t phi qua tri. Ta s tm hai ch s x
j
v x
i
u tin
ca x tnh t phi qua tri tha cc iu kin sau:
Thun th phi nht: x
i
< x
j
, 1 s i < j s N: x
i
ng trc x
j
v nh hn x
j
.
Nu khng tm c hai ch s nh vy tc l x[1..n] l dy c sp gim dn th mi hon v cc
ch s ca x khng th cho ra s ln hn x: bi ton v nghim.
Nu tm c mt thun th phi nht (x
i
, x
j
)

nh trn th ta sa x nh sau:
- i ch x
i
v x
j
,
- Lt li on x[i+1..n].
Vi th d x[1..6] = (2,3,9,5,2,1) ta tm c: i = 2, x[2] = 3, j = 4, x[4] = 5.
Sau khi hon v x[i] v x[j] ta thu c, x = (2,5,9,3,2,1)
S ny cn ln, nu lt li on x[3..6] s thu c, x = (2,5,1,2,3,9). y l s cn tm.
Di y l thut ton vn dng thun th phi nht to ra s st sau theo iu kin ca u bi.
1. Tm im gy: Duyt ngc x[1..n] tm i u tin tha x[i] < x[i+1]. Nu tm c i th
thc hin bc 2, ngc li: dng thut ton vi kt qu v nghim.
2. Tm im vt: Duyt ngc x[i..n] tm j u tin tha x[i] < x[j]. rng, nu
tm c i th j lun tn ti (?).
3. Hon v x[i] v x[j],
4. Lt on x[i+1..N ].
phc tp: C N v mi ch s c thm v x l khng qu 2 ln.
Hm Next di y sa trc tip x[1..n] thu c s st sau. V s x c th c n 1000 ch s
nn ta biu din x theo kiu mng k t vi khai bo type mc1 = array[0..1000] of char. Ta
cng s dng phn t x[0] lm lnh canh v khi tr x[0] := pred('0') l k t st trc ch s 0.
(* Pascal *)
function Next(var x: mc1; n: integer): Boolean;
var i,j: integer;
t: char;
begin
Next := false; x[0] := pred('0');
{ Tim diem gay } i := n - 1;
while (x[i] >= x[i + 1]) do i := i - 1;

55
{ x[i] < x[i+1] }
if (i = 0) then exit; { Ko co diem gay: vo nghiem }
{ Tim diem vuot } j := n;
while (x[j] <= x[i]) do j := j - 1;
{ Doi cho } t := x[i]; x[i] := x[j]; x[j] := t;
{ Lat doan x[i+1..n] } i := i + 1; j := n;
while (i < j) do
begin
t := x[i]; x[i] := x[j]; x[j] := t;
i := i + 1; j := j - 1;
end;
Next := true;
end;
// C#
static bool Next(char[] x, int n) {
int i, j ;
// Tim diem gay i
for (i = n - 2; i >= 0; --i)
if (x[i] < x[i+1]) break;
if (i < 0) return false; // vo nghiem
// Tim diem vuot
for (j = n-1; j > i; --j)
if (x[j] > x[i]) break;
char t = x[i]; x[i] = x[j]; x[j] = t; // Doi cho
// Lat doan x[i+1..n-1]
++i; j = n-1;
while (i < j){
t = x[i]; x[i] = x[j]; x[j] = t;
++i; --j;
}
return true;
}
Bi 2.3 Cc hon v
Olimpic Moscva
Lit k tng dn theo th t t in cc hon v ca cc s 1..N.
D liu vo: tp vn bn HV.INP cha
duy nht s N, 1 s N s 9.
D liu ra: tp vn bn HV.OUT
Mi dng mt hon v.

HV.INP HV.OUT

3


1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Thut ton
S dng hm Next trong bi trc. Khi tr cho x l hon v n v x = (1,2,,N).
phc tp cho hm Next: 2N, cho c bi: 2N(N!).

56
Trong cc chng trnh di y ta xy dng cc hm Next khng c tham bin nhm mc ch y
nhanh qu trnh tnh ton. Nh vy, d liu c cho di dng cc bin tng th, bao gm n - chiu di
ca cc hon v, x[0..n1] - mng cha hon v.
(* Pascal *)
(***************************************
Liet ke cac hoan vi cua 1..N
theo thu tu tang dan
***************************************)
program CacHoanVi;
uses crt;
const
bl = #32; mn = 10; fn = 'HV.INP'; gn = 'HV.OUT';
type
mb1 = array[0..mn] of byte;
var
x: mb1; { chua hoan vi }
n: byte; { Len(x) }
f,g: text; { input, output files }
procedure Doc;
begin
assign(f,fn); reset(f);readln(f,n); close(f);
end;
function Next: Boolean;
var i,j,t : byte;
begin
Next := false;
{ Tim diem gay }
i := n - 1;
while (x[i] >= x[i + 1]) do i := i - 1;
{ x[i] < x[i+1] }
if (i = 0) then exit;
j := n;
while (x[j] <= x[i]) do j := j - 1;
t := x[i]; x[i] := x[j]; x[j] := t;
i := i + 1; j := n;
while (i < j) do
begin
t := x[i]; x[i] := x[j]; x[j] := t;
i := i + 1; j := j - 1;
end;
Next := true;
end;
procedure Run;
var i: byte;
begin
Doc; x[0] := 0; // Dat linh canh
assign(g,gn); rewrite(g);
for i := 1 to n do x[i] := i;// Hoan vi don vi
repeat
for i := 1 to n do write(g,x[i],bl);
writeln(g);
until not Next;
close(g);
end;
BEGIN

57
Run;
END.
// C#
using System;
using System.IO;
namespace SangTao2 {
/*---------------------------------------
* Cac Hoan Vi
* Liet ke cac hoan vi (1,2,...,n)
* theo trat tu tu dien tang dan
* -------------------------------------*/
class CacHoanVi {
const string fn = "hv.inp";
const string gn = "hv.out";
static char[] x; // chua cac hoan vi
static int n; // so phan tu
static void Main(){
Run();
Console.ReadLine();
} // Main
static void Run() {
n = int.Parse((File.ReadAllText(fn)).Trim());
x = new char[n + 1];
for (int i = 0; i < n; ++i)
x[i] = (char) ('1' + i);
StreamWriter g = File.CreateText(gn);
do {
for (int i = 0; i < n; ++i) g.Write(x[i]);
g.WriteLine();
} while (Next());
g.Close();
XemKetQua();
}
// Hien thi du lieu de kiem tra
static void XemKetQua() {
Console.WriteLine(File.ReadAllText(fn));
Console.WriteLine(File.ReadAllText(gn));
}
static bool Next(){
int i, j;
// Tim diem gay i
for (i = n - 2; i >= 0; --i)
if (x[i] < x[i + 1]) break;
if (i < 0) return false; // vo nghiem
// Tim diem vuot
for (j = n - 1; j > i; --j)
if (x[j] > x[i]) break;
char t = x[i]; x[i] = x[j]; x[j] = t; // Doi cho
// Lat doan x[i+1..n-1]
++i; j = n - 1;
while (i < j){
t = x[i]; x[i] = x[j]; x[j] = t;
++i; --j;
}
return true;

58
}
} // CacHoanVi
} // SangTao2
Bi 2.4 T hp
Lit k cc t hp chp K ca N phn t 1..N theo th t t in tng dn.

D liu vo: tp vn bn TOHOP.INP
Dng u tin: hai s N v K cch nhau qua du cch,
1 s N s 9, K s N.
D liu ra: tp vn bn TOHOP.OUT
Mi dng mt t hp, cc s trn cng dng cch nhau
qua du cch.
Thut ton
Phng n 1. Ta khi tr cho mng x[1..K] l t hp nh
nht (1,2,,K). Sau ta dng hm Next sinh ra t hp st
sau ca x. Hm Next hot ng theo 2 pha nh sau:
Pha 1. D. Duyt ngc t K qua tri b qua nhng phn
t mang gi tr N2, N1, N ng cui mng. Nu sau khi d x
khng cn phn t no th kt thc vi Next = false vi ngha l
st sau t hp x khng cn t hp no. Th d, nu N = 7, K = 5,
x[1..5] = (2,3,5,6,7) th sau khi d ba phn t cui ca x ta thu
c i = 2, x[1..2] = (2,3). iu ny cho bit s cn t hp st sau.
Pha 2. Xp.
2.1. Tng phn t x[i] thm 1 n v. Tip tc vi th d trn ta thu c x[1..2] = (2,4)
2.2. Xp tip vo x cho K phn t theo trt t tng dn lin tc. Tip tc vi th d trn ta thu
c x[1..5] = (2,4,5,6,7).
Ta s dng phn t x[0] = N lm lnh canh.
(* Pascal, Phuong an 1 *)
function Next: Boolean;
var i, j, b: integer;
begin
Next := false; x[0] := N;
{ Pha 1. Do }
i := k; b := n - k;
while (x[i] = b + i) do i := i - 1;
if (i = 0) then exit;
{ Pha 2. Xep }
x[i] := x[i] + 1;
for j := i + 1 to k do x[j] := x[j-1] + 1;
Next := true;
end;
phc tp: cho hm Next: 2N, cho c bi: 2N.C
N
K
= (2N. N!) / (K! (N-K)!) .
Phng n 2. Ta ci tin hm Next nh sau. Gi s sau pha 1 ta thu c v tr i tha x[i]
nk+i. Ta gi v tr ny l v tr cp nht v s iu khin n thng qua mt bin v. Ta khi tr cho x v v
nh sau
for i := 1 to k do x[i] := i;
if (x[k] = n) then v := 0 else v := k;
Sau mi ln gi hm Next ta kim tra
TOHOP.INP TOHOP.OUT

5 3




1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5


59
Nu v = 0 th dng hm Next.
Nu v 0 ta thc hin pha 2 sau chnh li gi tr ca v nh sau:
Nu x[k] = n th tc l x[v..k] = (nkv, ..., n1, n) th ln gi Next tip theo s cp nht ti v tr v-1,
ngc li, nu x[k] n th ln gi Next tip theo s cp nht ti v tr k.
phc tp: cho hm Next: N. Cho c bi: N.C
N
K
= (N. N!) / (K! (N-K)!).
(* Pascal, Phng n 2 *)
(***************************************
To hop chap k cua n phan tu
PHUONG AN 2
***************************************)
program ToHopKN;
uses crt;
const
bl = #32; mn = 10; fn = 'TOHOP.INP'; gn = 'TOHOP.OUT';
type
mb1 = array[0..mn] of byte;
var
x: mb1;
n, k, v: byte;
f,g: text;
procedure Doc;
begin
assign(f,fn); reset(f); readln(f,n,k); close(f);
end;
function Next: Boolean;
var i: byte;
begin
Next := false;
if (v = 0) then exit;
{ Pha 2. Xep }
x[v] := x[v] + 1;
for i := v + 1 to k do x[i] := x[i-1] + 1;
if (x[k] = n) then v := v - 1 else v := k;
Next := true;
end;
procedure Run;
var i: byte;
begin
Doc;
assign(g,gn); rewrite(g);
for i := 1 to k do x[i] := i;
if (x[k] = n) then v := 0 else v := k;
repeat
for i := 1 to k do write(g,x[i],bl);
writeln(g);
until not Next;
close(g);
end;
BEGIN
Run;
END.
// C#
using System;

60
using System.IO;
namespace SangTao2 {
/*--------------------------------
To hop (Phuong an 2)
Liet ke cac to hop chap k
cua n phan tu 1, 2, , n
-------------------------------*/
class ToHop2 {
const string fn = "ToHop.inp";
const string gn = "ToHop.out";
static int[] x;
static int n = 0; // so phan tu nen
static int k = 0; // so phan tu trong 1 to hop
static int v = 0; // vi tri cap nhat trong x
static void Main() {
GhiToHop(); XemKetQua();
Console.WriteLine("fini"); Console.ReadLine();
} // Main
// Doc lai cac tep inp va out de kiem tra
static void XemKetQua() {
Console.WriteLine(File.ReadAllText(fn));
Console.WriteLine(File.ReadAllText(gn));
}
static bool Next(){
if (v == 0) return false;
++x[v];
for (int i = v + 1; i <= k; ++i) x[i] = x[i - 1] + 1;
v = (x[k] == n) ? v - 1 : k;
return true;
}
static void Doc(){
char[] cc = new char[] { '\n', ' ', '\t', '\r' };
string[] ss = (File.ReadAllText(fn)).Split(cc,
StringSplitOptions.RemoveEmptyEntries);
n = int.Parse(ss[0]); k = int.Parse(ss[1]);
}
static void GhiToHop(){
Doc();
// Tao tep ket qua ToHop.out
StreamWriter g = File.CreateText(gn);
// Khoi tri;
x = new int[k + 1];
for (int i = 1; i <= k; ++i) x[i] = i;
v = (x[k] == n) ? 0 : k;
do {
for (int i = 1; i <= k; ++i) g.Write(x[i] + " ");
g.WriteLine();
} while (Next());
g.Close();
}
} // ToHop2
} // SangTao2

Ch Bn c lu rng thut ton trn cho ra dy sp tng cc t hp v trong mi t hp cc thnh
phn cng c sp tng.

61
Bi 2.5 S Kapreka
S Kapreka mang tn nh ton hc n v c m t nh sau. l s t nhin x vit trong h
m B c ng K ch s khc nhau i mt v x = x x, trong x v x ln lt l cc s thu c
bng cch sp li cc ch s ca s x theo trt t gim v tng dn. Vi mi cp gi tr B v K hy tm
mt s Kapreka.

D liu vo: tp vn bn KAPREKA.INP
Dng u tin: hai s B v K cch nhau qua du cch,
2 s B s 10, K < B.
D liu ra: tp vn bn KAPREKA.OUT
S x vit trong h m B.
B d liu trn cho bit: Trong h m thp phn (B =
10), x = 6174 l s Kapreka c 4 ch s (khc nhau i mt),
x'' - x' = 7641 1467 = 6174 = x.
Thut ton
Ta da vo thut ton t hp Next ca bi trc, sinh ln
lt cc s K ch s trong h b. Lu rng h m b s dng b
ch s 1..(b1). Vi mi s x c sinh ra theo thut ton Next
ta tnh hiu y = x x, trong x l s thu c bng cch sp
li cc ch s ca x theo trt t gim dn v x tng dn. Nu y
ch cha cc ch s ca x th y chnh l mt s Kapreka. Do cc
t hp x c sinh ra cha cc ch s i mt khc nhau v
c sp tng, nn ta lun c x'' = x.
tm hiu ca hai s trong h b ta nn biu din ngc
cc s di dng mng K phn t nhn cc gi tr trong khong 0..b-1. Th d s x = 1234 trong h 10 s
c biu din l x[1..4] = (4,3,2,1).
Gi s x = (x
1
, x
2
,,x
K
) v y = (y
1
, y
2
,,y
K
). Ta tnh hiu z = x y = (z
1
, z
2
,,z
K
) theo qui tc
sau:
Tnh z = x + y* + 1, trong y* l dng b (b1) ca y.
Sau ta b i s nh cui cng.
Dng b (b 1) y* = (y
1
*, y
2
*,,y
K
*) ca s y c tnh nh sau: y
i
* = (b 1) y
i
, i = 1..K.
Th d, tnh 9217 468 trong h 10. Ta c x[1..4] = (7,1,2,9), y[1..4] = (8,6,4,0), do y*[1..4] =
(1,3,5,9). Vy x y = x + y* + 1 = (7,1,2,9) + (1,3,5,9) + (1,0,0,0) = (9,4,7,8). Kt qu l, 9217 468 =
8749.
Qui tc trn c gii thch nh sau. Xt cc s trong h m b. K hiu z = b1, khi s (z,
z,,z) gm K ch s z chnh l b
K
1 v y* = (b
K
1)y. Khi , x y = x y + (b
K
1) + 1 b
K
= x +
((b
K
1)y) + 1 b
K
= x + y* + 1 b
K
. Vic b s nh cui cng tng ng vi php tr b
K
vo kt qu.
Di y l th tc tnh hiu z = x y cho cc s vit ngc c ti a K ch s trong h b.
procedure Hieu;
var i,c,t: integer;
begin
c := 1; { so nho }
for i := 1 to K do
begin
t := x[i] + ((b-1)-y[i]) + c;
z[i] := t mod b;
c := t div b;
end;
end;
KAPREKA.INP KAPREKA.OUT

10 4




6174


Kaprekar D. R. (1905-1986) nh
ton hc n say m l thuyt s
t nh. Sau khi tt nghip i hc
Tng hp Bombay nm 1929 ng
lm gio vin ph thng ti Devlali,
n . ng vit nhiu bi kho cu
ni ting v l thuyt s, ma phng
v cc tnh cht k l ca th gii s.

62
rng php cng hai s mt ch s trong h m b > 1 bt k cho s nh ti a l 1. Ngoi ra do cc
php ton div v mod thc hin lu hn cc php cng v tr nn ta c th vit li th tc trn nh sau.
procedure Hieu;
var i,c,t: integer;
begin
c := 1;
for i := 1 to K do
begin
t := x[i] + (b-1-y[i]) + c;
if (t >= b) then
begin z[i] := t b; c := 1; end
else begin z[i] := t; c := 0; end;
end;
end;
Vi s x c K ch s sp tng tc l dng vit ngc ca x ta c th thc hin php tr y = x x bng
cc thao tc trn chnh x theo hai chiu duyt xui v ngc. Khi thc hin php ly hiu ta cng ng thi
kim tra xem mi ch s ca y c xut hin ng mt ln trong x hay khng. Nu ng, ta cho kt qu l
true, ngc li, ta cho kt qu false. thc hin vic ny ta dng mng d[1..K] nh du s xut hin
ca cc ch s trong x v y.
(*------------------------------
y = x'' - x' (he dem B)
-------------------------------*)
function Hieu: Boolean;
var i,c,t: integer;
begin
fillchar(d,sizeof(d),0); { mang danh dau }
Hieu := false;
{ Ghi nhan cac xuat hien cua x[i] }
for i := 1 to k do d[x[i]] := 1;
c := 1; { c: so nho }
for i := 1 to k do
begin
t := x[i] + (b - 1 - x[k-i+1]) + c;
if (t >= b) then
begin y[i] := t - b; c := 1; end
else begin y[i] := t; c := 0; end;
if (d[y[i]] = 0) then exit;
if (d[y[i]] = 1) then d[y[i]] := 0;
end;
Hieu := true;
end;
Di y cung cp 15 th d bn c test chng trnh. Kt qu 0 cho bit khng tn ti s
Kapreka cho trng hp .

NN B K p s N
N
B K p s N
N
B K p s
1 4 3 132 6 8 2 25 1
1
9 7 0
2 5 4 0 7 8 3 374 1
2
9 8 0
3 6 3 253 8 8 7 6417532 1
3
10 3 495

63
4 6 4 0 9 9 5 62853 1
4
10 4 6174
5 6 5 41532 1
0
9 6 0 1
5
10 9 864197532
15 th d v cc s Kapreka
(* Pascal *)
(***************************************
So Kapreka
***************************************)
program SoKapreka;
uses crt;
const mn = 11; fn = 'KAPREKA.INP'; gn = 'KAPREKA.OUT';
type mb1 = array[0..mn] of byte;
var x,y,d: mb1;
b,k,b1,v: integer;
{-------------------------------------------
b - he dem
k - so chu so
b1 - chu so lon nhat trong he b, b1 = b-1
v - bien kiem soat cho ham Next
---------------------------------------------}
f,g: text;
procedure Doc;
begin assign(f,fn); reset(f); readln(f,b,k); close(f);
b1 := b-1; { Chu so cao nhat trong he dem b }
end;
function Next: Boolean;
var i: integer;
begin
Next := false;
if (v = 0) then exit;
x[v] := x[v] + 1;
for i := v + 1 to k do x[i] := x[i-1] + 1;
if (x[k] = b1) then v := v - 1 else v := k;
Next := true;
end;
(*------------------------------
y = x'' - x'
-------------------------------*)
function Hieu: Boolean;
var i,c,t: integer;
begin
fillchar(d,sizeof(d),0);
Hieu := false;
{ Ghi nhan cac xuat hien cua x[i] }
for i := 1 to k do d[x[i]] := 1;
c := 1; { c: so nho }
for i := 1 to k do
begin
t := x[i] + (b1 - x[k-i+1]) + c;
if (t > b1) then
begin t := t - b; c := 1; end
else c := 0;

64
if (d[t] = 0) then exit; { t ko xuat hien trong x }
y[i] := t; d[t] := 0;
end;
Hieu := true;
end;
function Kapreka: Boolean;
var i: integer;
t: Boolean;
begin
Kapreka := true;
{ Khoi tri x la to hop tang nho nhat }
{ x[1..k] = (0,1,...,k-1) }
for i := 1 to k do x[i] := i-1;
if (x[k] = b1) then v := 0 else v := k;
repeat
if (Hieu) then exit;
until not next;
Kapreka := false;
end;
procedure Run;
var i: byte;
begin
Doc;
assign(g,gn); rewrite(g);
if (Kapreka) then
for i := k downto 1 do write(g,y[i])
else write(g,0);
writeln(g); close(g);
end;
BEGIN
Run;
END.
// C#
using System;
using System.IO;
namespace SangTao2 {
/*-------------------------------------------
* So Kapreka
* x'' - x' = x
* x'' - so giam
* x' - so tang
* ------------------------------------------*/
class Kapreka {
const string fn = "Kapreka.inp";
const string gn = "Kapreka.out";
static int[] x; // so x
static int[] y; // y = x'' - x'
static int[] d;
static int b; // he dem
static int k; // so chu so
static int b1; // b-1: chu so cao nhat trong he b
static int v; // bien cam canh
static void Main() {
Doc(); Ghi(Kap()); XemKetQua();
Console.WriteLine("\n fini");

65
Console.ReadLine();
} // Main
static void Ghi(int ket){
StreamWriter g = File.CreateText(gn);
if (ket == 0) g.WriteLine(0);
else for (int i = k; i > 0; --i) g.Write(y[i]);
g.Close();
}
// Doc lai cac tep inp va out de kiem tra
static void XemKetQua(): t vit
static bool Next() {
if (v == 0) return false;
++x[v];
int j = x[v] + 1;
for (int i = v + 1; i <= k; ++i, ++j) x[i] = j;
v = (x[k] == b1) ? v - 1 : k;
return true;
}
static void Doc() {
char[] cc = new char[] { '\n', ' ', '\t', '\r' };
string[] ss = (File.ReadAllText(fn)).Split(cc,
StringSplitOptions.RemoveEmptyEntries);
b = int.Parse(ss[0]); // he dem
k = int.Parse(ss[1]); // so chu so
b1 = b - 1; // chu so cao nhat cua he dem b
}
// y = x'' - x'
static bool Hieu() {
int c = 1, t = 0;
Array.Clear(d, 0, d.Length);
for (int i = 1; i <= k; ++i) d[x[i]] = 1;
for (int i = 1; i <= k; ++i){
t = x[i] + (b1 - x[k - i + 1]) + c;
if (t > b1) { c = 1; t = t - b; }
else c = 0;
if (d[t] == 0) return false;
y[i] = t; d[t] = 0;
}
return true;
}
static int Kap() { // Khoi tri;
x = new int[k + 1];
y = new int[k + 1];
d = new int[b];
for (int i = 1; i <= k; ++i) x[i] = i - 1;
v = (x[k] == b1) ? 0 : k;
do {
if (Hieu()) return 1;
} while (Next());
return 0;
}
} // class Kapreka
} // SangTao2

Ch thch
Bn c th s dng thut ton sau y:

66
Khi tr: To s x h b gm k ch s khc nhau;
Lp t 1 n b
k
1
Tnh y = x'' x';
Nu x = y th cho kt qu x l s Kapreka; stop;
Nu khng gn x := y;
Xong lp.
Bi 2.6 Kha vng
Mt kha gm M vng ch v N vng s. Mi vng ch hoc s cha cc gi tr bin thin t gii
hn nh nht a n gii hn ln nht b. Hy lit k tng dn theo trt t t in cc gi tr c th c ca
kha.

D liu vo: tp vn bn KHOA.INP
Dng u tin: hai s t nhin M v N, 1 s M, N s 5.
Dng th i trong s M+N dng tip theo: gii hn a
i
v b
i

cho cc vng kha.
D liu ra: tp vn bn KHOA.OUT
Dng u tin: Tng s kh nng.
T dng th hai tr i: mi dng mt gi tr kha lit k
tng dn theo trt t t in. Cc k t ch v s trong mi kha
c vit lin nhau, khng c du cch gia. Cc gi tr ch
c ly t bng ch HOA ting Anh.
Thut ton
Phng php: duyt ton b cc t hp.
Nu ton b N vng kha u ch cha cc ch s vi gii
hn bit trc t cn di a[i] n cn trn b[i] , i = 1..N th ta
dng hm Next sinh ra ln lt cc t hp N phn t c[1..N] nh
sau.


Khi tr: c[1..N] l t hp nh nht cha ton cn di:
c[i] := a[i], i = 1..N.
X l:
repeat
Ghi t hp c[1..N];
until not Next;
Mi ln gi hm Next ta thc hin ging nh php m: Duyt ngc c[1..N] vi mi c[i] = b[i] ta
t li c[i] := a[i]. Gp c[i] u tin tha iu kin c[i] < b[i] th tng vng kha i thm 1 nc. Nu khng
gp phn t i nh vy th chng t x l xong t hp cao nht.
Vic cn li l chuyn cc vng ch sang vng s tng ng.
phc tp: (b
1
-a
1
+1)(b
2
-a
2
+1)...(b
v
-a
v
+1), v = M+N.
(* Pascal *)
(****************************************
Khoa Vong
*****************************************)
program KhoaVong;
uses crt;
const mn = 20;
KHOA.INP KHOA.OUT

1 2
B C
2 3
0 2


12
B20
B21
B22
B30
B31
B32
C20
C21
C22
C30
C31
C32


67
bl = #32; nl = #13#10; fn = 'KHOA.INP'; gn = 'KHOA.OUT';
ChuCai = ['A'..'Z'];
type mi1 = array[0..mn] of integer;
var m,n: integer;
a,b,c: mi1;
f,g: text;
m: longint;
procedure Doc;
var i: integer;
c: char;
begin
assign(f,fn); reset(f); readln(f,m,n);
n := m + n;
for i := 1 to m do
begin
repeat
read(f,c);
until c in ChuCai;
a[i] := ord(c) - ord('A');
repeat
read(f,c);
until c in ChuCai;
b[i] := ord(c) - ord('A');
end;
for i := m + 1 to n do read(f,a[i],b[i]);
close(f);
m := 1;
for i := 1 to n do m := m * (b[i] - a[i] + 1);
end;
function Min(a,b: integer): integer;
begin
if (a < b) then Min := a else Min := b;
end;
function Next: Boolean;
var i: integer;
begin
Next := false;
i := n;
while (c[i] = b[i]) do
begin
c[i] := a[i];
i := i - 1;
end;
if (i = 0) then exit;
c[i] := c[i] + 1;
Next := true;
end;
procedure Duyet;
var i: integer;
begin
for i := 1 to n do c[i] := a[i];
c[0] := -1;
assign(g,gn); rewrite(g); writeln(g,m);
repeat
for i := 1 to m do write(g,chr(ord('A')+c[i]));
for i := m + 1 to n do write(g,c[i]);
writeln(g);

68
until not Next;
close(g);
end;
BEGIN
Doc; Duyet;
END.
// C#
using System;
using System.IO;
namespace SangTao2 {
/*-------------------------------------------
* Khoa Vong
* ------------------------------------------*/
class KhoaVong {
const string fn = "Khoa.inp";
const string gn = "Khoa.out";
static int [] x; // to hop
static int[] vmin; // can duoi
static int[] vmax; // can tren
static int m; // so luong vong chu
static int n; // so luong vong so
static int mn; // m+n
static void Main() {
Doc(); Ghi(); XemKetQua(); Console.ReadLine();
} // Main
// Doc lai cac tep inp va out de kiem tra
static void XemKetQua(): t vit
static bool Next() {
int i;
for (i = mn - 1; i >= 0; --i)
if (x[i] == vmax[i]) x[i] = vmin[i];
else break;
if (i < 0) return false;
++x[i];
return true;
}
static void Doc() {
char [] cc = new char [] {'\n',' ','\t','\r'};
string [] ss = (File.ReadAllText(fn)).Split(cc,
StringSplitOptions.RemoveEmptyEntries);
int k = 0;
m = int.Parse(ss[k++]); // m vong chu
n = int.Parse(ss[k++]); // n vong so
mn = m + n;
vmin = new int [mn];
vmax = new int [mn];
for (int i = 0; i < m; ++i) {
vmin[i] = (int)ss[k++][0] - (int)'A';
vmax[i] = (int)ss[k++][0] - (int)'A';
}
for (int i = m; i < mn; ++i) {
vmin[i] = int.Parse(ss[k++]);
vmax[i] = int.Parse(ss[k++]);
}
}

69
static void Ghi() {
StreamWriter g = File.CreateText(gn);
// khoi tri x
x = new int[mn];
for (int i = 0; i < mn; ++i) x[i] = vmin[i];
do {
for (int i = 0; i < m; ++i)
g.Write((char)(x[i] + (int)'A'));
for (int i = m ; i < mn; ++i)
g.Write(x[i]);
g.WriteLine();
} while (Next());
g.Close();
}
} // KhoaVong
} // SangTao2
Bi 2.7 Tr tin
C N loi tin mnh gi m
i
v s lng s
i
, i = 1..N. Xc nh s lng mi loi c th tr li V
ng.

D liu vo: tp vn bn TRATIEN.INP
Dng u tin: hai s t nhin N v V, 2 s N s 15.
Dng th hai: N s t nhin m
1
, m
2
,,m
N
.
Dng th ba: N s t nhin s
1
, s
2
,,s
N
.
D liu ra: tp vn bn TRATIEN.OUT
N s t nhin c
1
, c
2
,,c
N
th hin s lng t tin
mi loi cn tr, c
1
m
1
+ c
2
m
2
+ + c
N
m
N
= V. Nu v
nghim: ghi s 0.
Trong cc tp *.INP v *.OUT cc s trn cng dng cch nhau qua du cch.
Thut ton
y l loi ton Balo vi d liu nh v trong thc t s mnh gi khng nhiu, th d, tin Vit ch
c cc loi sau y l thng dng 100, 200, 500, 1.000, 2.000, 5.000, 10.000, 20.000, 50.000, 100.000,
200.000, 500.000. Nu tnh theo n v 100 ng th ta c th vit li dy trn cho gn hn nh sau:
1, 2, 5, 10, 20, 50, 100, 200, 500, 1.000, 2.000, 5.000.
Ta duyt cc t hp s t tin phi tr cho mi loi mnh ga, cn di l 0 cn trn l min(s
i
, v div
m
i
) v tr li v ng bng loi mnh gi m
i
ta dng ti a (v div m
i
) t.
phc tp: (b
1
-a
1
+1)(b
2
-a
2
+1)...(b
v
-a
v
+1), v = M+N.
Ch : Sau ny ta s xy dng thut ton tt hn cho bi ton tr tin. Thut ton ny da trn mt
s kin thc s hc.
(* Pascal *)
(****************************************
Tra tien
*****************************************)
program TraTien;
uses crt;
const mn = 20; bl = #32; nl = #13#10;
fn = 'TRATIEN.INP'; gn = 'TRATIEN.OUT';
type mi1 = array[0..mn] of integer;
TRATIEN.INP TRATIEN.OUT

6 156
1 2 5 10 20 50
4 7 2 3 6 2


0 3 0 0 5 1




70
(*----------------------------------
n so luong cac loai tien
v so tien can tra lai
vt gia tri tam thoi
m[1..n] cac menh gia
s[1..n] so luong to tien
c[1..n] so luong can chon
------------------------------------*)
var n,v,vt: integer;
m,s,c: mi1;
f,g: text;
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f); readln(f,n,v);
for i := 1 to n do read(f,m[i]);
for i := 1 to n do read(f,s[i]);
close(f);
end;
function Min(a,b: integer): t vit
function Next: Boolean;
var i: integer;
begin
Next := false;
i := n;
while (c[i] = s[i]) do
begin
vt := vt - c[i] * m[i];
c[i] := 0;
i := i - 1;
end;
if (i = 0) then exit;
c[i] := c[i] + 1;
vt := vt + m[i];
Next := true;
end;
function Duyet: Boolean;
var i: integer;
begin
{ Khoi tri }
for i := 1 to n do
begin
s[i] := min(s[i],v div m[i]);
c[i] := 0;
end;
c[0] := -1; vt := 0; { tong gia tri cua 1 phuong an }
Duyet := true;
repeat
if (vt = v) then exit;
until not Next;
Duyet := false;
end;
procedure Run;
var i: integer;
begin
Doc; assign(g,gn); rewrite(g);
if (Duyet) then

71
for i := 1 to n do write(g,c[i],bl);
else writeln(g,0);
close(g);
end;
BEGIN
Run;
END.
// C#
using System;
using System.IO;
namespace SangTao2 {
/*-------------------------------------------
* Tra Tien
* ------------------------------------------*/
class TraTien {
const string fn = "TraTien.inp";
const string gn = "TraTien.out";
static int[] c; // phuong an dang duyet
static int[] s; // so luong to tien
static int[] m; // menh gia
static int n; // so luong menh gia
static int v; // tong so tien can tra
static int t; // tong so tien cua 1 phuong an
static void Main() {
Doc();
int kq = XuLi();
Ghi(kq);
} // Main
static bool Next() {
int i = n;
while (c[i] == s[i]) { t -= c[i] * m[i]; c[i] = 0; --i; }
if (i == 0) return false;
++c[i]; t += m[i]; return true;
}
static void Doc() {
char[] cc = new char[] { '\n', ' ', '\t', '\r' };
string[] ss = (File.ReadAllText(fn)).Split(cc,
StringSplitOptions.RemoveEmptyEntries);
int k = 0;
n = int.Parse(ss[k++]); // n so luong tien
v = int.Parse(ss[k++]); // v so tien can tra lai
m = new int[n + 1]; // cac menh gia
s = new int[n + 1]; // so luong to moi loai
for (int i = 1; i <= n; ++i)
m[i] = int.Parse(ss[k++]);
for (int i = 1; i <= n; ++i)
s[i] = Min(v/m[i], int.Parse(ss[k++]));
}
static int Min(int a, int b) { return (a < b) ? a : b; }
static int XuLi() {
c = new int[n + 1];
for (int i = 1; i <= n; ++i) c[i] = 0;
t = 0;
do { if (t == v) return 1; } while (Next());
return 0;

72
}
static void Ghi(int kq) {
StreamWriter g = File.CreateText(gn);
if (kq == 0) g.WriteLine(kq);
else for (int i = 1; i <= n; ++i) g.Write(c[i] + " ");
g.Close();
}
} // TraTien
} // SangTao2
Bi 2.8 Dy Farey
Cho s t nhin N > 0. hy lit k theo trt t tng dn cc phn s t / m tha ng thi cc
tnh cht sau:
- t / m l phn s ti gin bin thin trong khong 0..1,
- m bin thin trong khong 1..N.

D liu vo: tp vn bn FAREY.INPcha s N.
D liu ra: tp vn bn FAREY.OUT
Dng th nht: D s lng cc phn s trong dy.
T dng th hai: mi dng hai s t nhin t m ghi cch
nhau qua du cch, th hin mt phn s trong dy sp
tng.
Thut ton
Nu sinh ln lt cc phn s (PS) ri sp xp th
kh tn b nh v ti a phi dnh b nh lu tr
n
2
PS.

Phng n 1. Nu
t/m v a/b l hai
PS s lin tip
trong dy Farey
th
a/b = min { x/y | x/y > t/m, y = 1..n, x s y, (x,y) = 1 }
trong (x,y) l c chung ln nht ca x v y.
Cc PS x/y trong tp trn c gi l cc ng vin. Ta s c cng t ng vin cng tt.
Vi y = 1, do x s y nn ta c ngay PS 1/1 l phn t ln nht trong dy.
Vi mi y = 2..n ta xt PS x/y l PS u tin ln hn t/m.
Ta c t t/m < x/y ta suy ra mx > ty nn x > (ty div m). Nu bit m ta chn x = (ty div m) +1 s thu
c PS x/y tha ng thi cc tnh cht sau:
- 1 s m s n
- x/y l PS u tin ln hn t/m.
c t trn c thu gn li vi n1 ng vin nh sau,
a/b = min { x/y | y = 2..n, x = (ty div m) + 1 }
Nh vy, nu sinh c PS t/m cho dy Farey th PS tip theo a/b s c chn l PS nh nht
trong tp n1 PS ni trn. rng 0/1 l PS u tin v 1/1 l PS cui cng ca dy Farey. Th tc
Next(n,t,m) trong phng n 1 s xc nh PS a/b st sau PS t/m trong dy Farey. Gi tr tm c s t
ngay trong t/m.
FAREY.INP FAREY.OUT

5


11
0 1
1 5
1 4
1 3
2 5
1 2
3 5
2 3
3 4
4 5
1 1

Farey l nh a cht hc ngi
Anh. ng m t dy phn s trn
vo nm 1816.


73
phc tp. Xut pht t PS u tin 0/1, mi ln ta phi sinh ra n1 ng vin t chn ra 1
PS trong dy. Nu dy c s PS th ta phi thc hin s(n1) php ton trn cc PS. Gi tr max ca s l n
2
.
Vy phc tp tnh ton vo c n
3
.
Bnh lun
Nu t PS t/m trong dy Farey v gi tr mu s y trong khong 2..n cho trc ta sinh ra PS x/y
thng qua h thc x = (ty div m) + 1 th PS x/y c th cha ti gin. Th d, vi n = 15, t/m = 3/4, y = 12 ta
c x = (ty div m)+1 = 10 th PS 10/12 khng ti gin do ta cn gi th tc RutGon gin c PS x/y.
V khng tnh trc c s lng cc PS trong dy nn ta cn m dn v ghi tm dy PS vo tp
FAREY.TMP. Sau m tp FAREY.OUT ghi s lng s v chuyn d liu t tp FAREY.TMP sang tp
FAREY.OUT, cui cng xa tp FAREY.TMP.
Phng n 2. Ta c th sinh dn cc phn t cho dy Farey nh sau. Cho hai PS a/b v c/d, PS
(a+c)/(b+d) c gi l PS trung bnh ca hai PS ny.
Nhn xt. Nu t
1
/ m
1
, t
2
/ m
2
, t
3
/ m
3
l ba PS lin tip trong dy Farey th PS gia l PS trung
bnh ca hai PS kia.
Ta c thut ton sau:
Xut pht vi mu s m = 1 ta c dy 2 PS: 0/1, 1/1.
Vi mi mu s m = 2..n ta sinh cc PS trung bnh c mu s m ca hai PS k nhau trong dy trc
v xen PS ny vo gia hai PS sinh ra n dn vo trong dy kt qu.
m = 2: thm cc PS trung bnh vi mu bng 2: 0/1, 1/2 , 1/1.
m = 3: thm cc PS trung bnh vi mu bng 3: 0/1, 1/3, 1/2, 2/3, 1/1.
...
Cc phn s mi sinh trong mi ln duyt c gch di.
Ta dng hai mng: a lu cc PS ca dy trc, b lu cc PS ca dy sau. Sau mi bc lp ta
chuyn b qua a. D liu c m t nh sau:
const mn = 1000;
type
PS = record tu,mau: byte end;
mps = array[0..mn] of PS; { mng cc PS }
var a,b: mps;
phc tp. Thi gian: n
3
, min nh : 2 mng kch thc n
2
.
Phng n 3. Ta s dng mt s tnh cht ca dy Farey tip tc ci tin thut ton.
Nu t
1
/ m
1
, t
2
/ m
2
, t
3
/ m
3
l ba PS lin tip trong dy Farey th
1. t
2
m
1
t
1
m
2
= 1,
2. m
1
+ m
2
> n,
3. t
2
/ m
2
= (t
1
+ t
3
) / (m
1
+ m
3
),
4. t
3
= vt
2
t
1
, m
3
= vm
2
m
1
vi v = (m
1
+ n) div m
2
.
T tnh cht 4 ta suy ra ngay cch xc nh PS t3/m3 thng qua hai PS st trc.
Cc trnh di y minh ha 3 phng n vi cc kt qu hin th trn mn hnh bn c c th
theo di.
(* Pascal *)
(*------------------------------------*
Ba phuong an cho bai Day Farey
*-------------------------------------*)
uses crt;
const bl = #32; nl = #13#10;
var n: integer;
{ Uoc chung lon nhat cua hai so tu nhien a, b }
function Ucln(a,b:integer):integer;

74
var r: integer;
begin
while b > 0 do begin r := a mod b; a := b; b:=r end;
Ucln:=a;
end;
{ Rut gon PS a/b thanh PS t/m }
procedure RutGon(a,b:integer; var t,m:integer);
var d:integer;
begin d :=Ucln(a,b); t := a div d; m := b div d; end;
{ Tim PS sat sau PS t/m, ket qua dat trong t/m }
function Next(n: integer; var t,m: integer): Boolean;
var a,b,x,y: integer;
begin
if (t+m=2) then begin Next := false; exit end;
a := 1; b := 1;
for y := 2 to n do
begin
x := t*y div m + 1;
if a*y > b*x then begin a := x; b:=y end;
end;
RutGon(a,b,t,m); Next := true;
end;
procedure Farey1(n: integer);
var t,m,d:integer;
begin
writeln(nl,'Farey1'); d := 0;
t := 0; m := 1;
repeat
write(t,'/',m,bl); inc(d);
until not Next(n,t,m);
writeln(nl,'Total: ',d,' PS');
readln;
end;
procedure Farey2(n: byte);
const mn = 1000;
type PS = record tu,mau: byte end;
mps1 = array[0..mn] of PS;
var a,b: mps1; { 2 day PS a , b }
d,k,i,m:integer;
begin
writeln(nl,'Farey2'); d := 2;
a[1].tu := 0; a[1].mau := 1; { PS dau day }
a[2].tu := 1; a[2].mau := 1; { PS thu hai }
for m:=2 to n do
begin
k := 0; inc(k); b[k] := a[k];
for i := 2 to d do
begin
if a[i].mau+a[i-1].mau = m then
begin
inc(k); b[k].tu := a[i-1].tu + a[i].tu;
b[k].mau := a[i-1].mau + a[i].mau;
end;
inc(k); b[k] := a[i];
end;
a := b; d := k;
end;

75
for i := 1 to d do write(a[i].tu,'/',a[i].mau,bl);
writeln(nl,'Total ',d,' PS');
readln;
end;
procedure Farey3(n: integer);
var t1,m1,t2,m2,t3,m3,v,d: integer;
begin
writeln(nl,'Farey3'); d := 2;
t1 := 0; m1 := 1; { PS dau day }
t2 := 1; m2 := n; { PS thu hai }
write(t1,'/',m1,bl,t2,'/',m2,bl);
while (t2 + m2 <> 2) do
begin
v := (m1+n) div m2;
t3 := v*t2 - t1; m3 := v*m2 - m1;
write(t3,'/',m3,bl); inc(d);
t1 := t2; t2 := t3;
m1 := m2; m2 := m3;
end;
writeln(nl,'Total ',d,' PS'); readln;
end;
BEGIN
n := 5;
Farey1(n); Farey2(n); Farey3(n);
END.
// C#
using System;
using System.IO;
namespace SangTao2 {
/*-------------------------------------------*
Ba phuong an cho bai Day Farey
* ------------------------------------------*/
class Farey {

static void Main() {
int n = 10;
Farey1 x = new Farey1(); x.Run(n); Console.ReadLine();
(new Farey2()).Run(n); Console.ReadLine();
(new Farey3()).Run(n); Console.ReadLine();
Console.WriteLine("\n fini");
Console.ReadLine();
} // Main
} // Farey
class Farey1 {
public Farey1() { }
public void Run(int n) {
int d = 0;
int t = 0, m = 1; // PS dau day
do {
Console.Write(t + "/" + m + " ");
++d;
} while (Next(n, ref t, ref m));
Console.WriteLine(" * Farey1: Total " + d + " PS");
}
public bool Next(int n, ref int t, ref int m) {

76
if (t + m == 2) return false;
int a = 1, b = 1, x, y;
for (y = 2; y <= n; ++y) {
x = t * y / m + 1;
if (a * y > b * x) { a = x; b = y; }
}
RutGon(a, b, ref t, ref m);
return true;
}
Console.WriteLine(" * Farey1: Total " + d + " PS");
}
public void Next(int n, ref int t, ref int m) {
int a = 1, b = 1, x, y;
for (y = 2; y <= n; ++y) {
x = t * y / m + 1;
if (a * y > b * x) { a = x; b = y; }
}
RutGon(a, b, ref t, ref m);
}
public int Ucln(int a, int b) {
int r;
while (b != 0) { r = a % b; a = b; b = r; }
return a;
}
public void RutGon(int a, int b, ref int t, ref int m)
{ int d = Ucln(a, b); t = a / d; m = b / d; }
} // Farey1
class Farey2 {
public Farey2() { }
public void Run(int n) {
int mn = 10000;
PS[] a = new PS[mn];
PS[] b = new PS[mn];
int d = 0;
a[d++] = new PS(0, 1); //PS dau day
a[d++] = new PS(1, 1); // PS cuoi day
for (int m = 2; m <= n; ++m) {
int k = 0; b[k++] = a[0];
for (int i = 1; i < d; ++i) {
if (a[i].mau + a[i - 1].mau == m)
b[k++] = new PS(a[i], a[i - 1]);
b[k++] = a[i];
}
d = k; Array.Copy(b, 0, a, 0, d);
}
for (int i = 0; i < d; ++i) a[i].Print();
Console.WriteLine(" * Farey2: Total " + d + " PS");
}
public struct PS {
public int tu, mau;
public PS(int t, int m) { tu = t; mau = m; }
public PS(PS x, PS y)
{ tu = x.tu + y.tu; mau = x.mau + y.mau; }
public void Print()
{ Console.Write(tu + "/" + mau + " "); }
} // PS
} // Farey2

77
class Farey3 {
public Farey3() { }
public void Run(int n) {
int d = 2;
int t1 = 0, m1 = 1, t2 = 1, m2 = n; // hai PS dau day
int t3, m3, v;
Console.Write(t1 + "/" + m1 + " " + t2 + "/" + m2 + " ");
while (t2 + m2 != 2) {
++d; v = (m1 + n) / m2;
t3 = v * t2 - t1; m3 = v * m2 - m1;
Console.Write(t3 + "/" + m3 + " ");
t1 = t2; m1 = m2; t2 = t3; m2 = m3;
}
Console.WriteLine(" * Farey3: Total " + d + " PS");
}
} // Farey3
} // SangTao2
Bi 2.9 Qy Mi
Minh mun lm mt thip chc tt Qu Mi c nn c to bi 2
n
dng, mi dng l mt dy k t
gm n ch ci Q v M sao cho hai dng k nhau khc nhau ti ng mt v tr, dng cui cng cng
c coi l k vi dng u tin. Gi s bn c th gip Minh lm iu . Vi mi gi tr n v k cho trc
bn hy hin th dng th k trong tm thip trn. Cc dng c m s t 1 tr i, 1 s n s 30.
Thut ton
K hiu T(n) l tm thip c thit k vi gi tr n cho
trc. T(n) dng y s cha 2
n
dng. T(1) cha hai dng l
Q v M. Gi s ta thit k xong T(n1), khi T(n) s c
thit k theo 3 bc sau.
Bc 1. Lt: Lt T(n1) xung pha di, tc l ly i xng
qua ng k ngang cui tm thip. Ta k hiu phn i xng ca
T(n1) l T*(n1).
Bc 2. Thm Q: Vit thm k t Q vo mi dy ca
T(n1).
Bc 3. Thm M: Vit thm k t M vo mi dy ca
T*(n1).
Ta c th vit thm k t vo u hoc cui dy. Trong bi
ny ta chn u dy.
D dng chng minh rng thut ton trn sinh ra cc tm
thip tha cc yu cu ca u bi. Tht vy, ta gi P l tnh cht Hai dng k nhau khc nhau ti ng
mt v tr. Khi T(1) tha P l hin nhin v n ch cha 2 dng Q v M. Gi s T(n1) tha P. Khi
ng nhin T*(n1) cng tha P. Do php i xng, dng cui cng ca T(n1) v dng u tin ca
T*(n1) ging nhau nn khi thm Q cho dng trn v M cho dng di chng s khc nhau ti v tr
thm . Tng t, dng u tin ca T(n1) v dng cui cng ca T*(n1) ging nhau nn khi thm Q
cho dng u v M cho dng cui chng s khc nhau ti v tr thm.
Da theo thut ton trn ta vit hm Line(n,k) sinh ra dng th k trn tm thip T(n). Th d,
Line(3,7) = MQM. Hm s lp n ln, mi ln sinh 1 k t theo chiu ngc li vi kin thit trn. Ta
thy, nu k > 2
n1
th chng t dng k nm trong T*(n1), do k t u dng ca n s phi l M v
dng t T(n1) lt xung dng k s c ch s 2
n
k+1, ngc li, nu k s 2
n1
th dng k nm trong T(n1),
do k t u dng ca n l Q.
(* Pascal *)
n = 1 n = 2 n = 3
Q
M
Q
M
QQ
QM
QQ
QM
MM
MQ
QQQ
QQM
QMM
QMQ
M
Q
MM
MQ
MQ
MM
QM
QQ
MMQ
MMM
MQM
MQQ

Thit k cc thip T(1), T(2) v T(3)

78
function Line(n: integer; k: longint): string;
var s: string; m: longint; i: integer;
begin
m := 1; m := m shl n; { m = 2^n }
for i := n downto 1 do
begin
m := m shr 1; { m div 2 }
if (k <= m) then s := s + Q
else
begin
s := s + M; k := 2*m k + 1;
end;
end;
Line := s;
end;
// C#
static public string Line(int n, int k) {
string s = "";
int m = 1 << n; // m = 2^n
for (int i = n-1; i >= 0; --i) {
m >>= 1;
if (k <= m) s += 'Q';
else { s += 'M'; k = 2*m - k + 1; }
}
return s;
}
phc tp. n.
Ch thch. Kiu int trong C# tng ng vi kiu longint trong Pascal.
M Gray
M Gray ca mt s t nhin k l s (k shr 1) xor k = (k div 2) xor k, trong xor l php ton cng
loi tr theo bt: a xor b = 0 khi v ch khi a = b.
Cc tnh cht ca m Gray
1. M Gray ca hai s t nhin khc nhau th khc nhau: k
1
= k
2
Gray(k
1
) = Gray(k
2
).


2. M Gray ca hai s t nhin lin tip khc nhau ti ng 1 bit.
3. Gay(0) = 0; Gray(1) = 1;
4. Nu s x c n bit th Gray(2
n
1) = 2
n

1
.

k Gray(k) GLine(4,k) k Gray(k) GLine(4,k)
0: 0000
1: 0001
2: 0010
3: 0011
4: 0100
5: 0101
6: 0110
7: 0111
0: 0000
1: 0001
3: 0011
2: 0010
6: 0110
7: 0111
5: 0101
4: 0100
QQQQ
QQQM
QQMM
QQMQ
QMMQ
QMMM
QMQM
QMQQ
8: 1000
9: 1001
10: 1010
11: 1011
12: 1100
13: 1101
14: 1110
15: 1111
12: 1100
13: 1101
15: 1111
14: 1110
10: 1010
11: 1011
9: 1001
8: 1000
MMQQ
MMQM
MMMM
MMMQ
MQMQ
MQMM
MQQM
MQQQ
M Gray v gi tr ca hm Gline ca 16

79
s t nhin u tin k = 0..15.

Nh m Gray ta c th vit hm GLine(n,k) cho ra dng
k trong thip T(n) mt cch n gin nh sau:
Bc 1. Tnh x = Gray(k) = (k shr 1) xor k = (k div 2)
xor k.
Bc 2. Xt n bit thp ca x, nu l 1 th vit M nu l
0 th vit Q.
(* Pascal *)
function Gray(k: longint): longint;
begin Gray := (k shr 1) xor k end;
function Gline(n: integer; k: longint): string;
var s: string; i: integer;
const cc: array[0..1] of char = ('Q','M');
begin
k := Gray(k); s = ;
for i := n-1 downto 0 do
s = s + cc[(k shr i) and 1];
GLine := s;
end;
// C#
static public int Gray(int k){ return (k >> 1) ^ k; }
static public string GLine(int n, int k) {
string cc = "QM";
string s = "";
k = Gray(k);
for (int i = n-1; i >= 0; --i)
s += cc[(k >> i) & 1];
return s;
}
Bi 2.10 Tng on
Mt dy con gm cc phn t lin tip nhau trong mt dy cho trc c gi l on. Cho dy
gm N s t nhin. Tm on ngn nht c tng cc phn t bng gi tr K cho trc.

D liu vo: tp vn bn TDOAN.INP
Dng th nht: hai s t nhin N v K,
1 s N s 2000.
T dng th hai tr i: cc phn t ca dy.
D liu ra: tp vn bn TDOAN.OUT
Cha mt dng duy nht gm hai s t nhin d
ch s u on v L s phn t trong on (chiu
di on). Nu v nghim th ghi 0 0.
Trong cc tp, d liu trn cng dng cch
nhau qua du cch.
Thut ton
Frank Gray l nh vt l hc M lm nghin
cu vin ti hng Bell Labs vi hng lot pht
minh c gi tr c ng dng trong truyn
hnh, c hc, in t v ton hc. Nm 1947
Gray ng k bng pht minh v m nh phn
phn hi sau ny c gi l m Gray.
TDOAN.INP TDOAN.OUT

21 17
0 2 3 2 10
1 5 5 6 12
20 30 14 8 0
11 0 6 0 0
5

16 3



80
Ta gii bng k thut ca s trt nh sau. Xt on a[i..j] vi tng S = a[i] + a[i+1] + + a[j], i s
j. on ny c gi l ca s. Ta cho ca s ny trt dn qua phi v xt ba tnh hung sau y.
1) (S = K): ta ghi nhn im u i v di on l ji+1. Nu di ny nh hn di LMin th
ta cp nht li cc gi tr iMin v Lmin (th tc Update). Ri tip tc xt ca s mi l a[i+1..j] .
2) (S < K): Ta dch u phi ca ca s t j sang j+1, gi nguyn u tri (th tc Right).
3) (S > K): Ta co u tri ca ca s t i thnh i+1 (th tc Left).
Ta t phn t a[n+1] = 0 lm lnh canh.
(****************************************
TONG DOAN - Doan ngan nhat
co tong K
****************************************)
program TDoan;
uses crt;
const
mn = 2001; bl = #32;
fn = 'TDOAN.INP'; gn = 'TDOAN.OUT';
type mw1 = array[0..mn] of word;
var f,g: text;
n,k: word;
a: mw1;
iMin, LMin: word;
iLeft,iRight: word;
sum: word;
procedure Doc;
var i: word;
begin
assign(f,fn); reset(f); readln(f,n, k);
for i := 1 to n do read(f,a[i]);
close(f);
end;
procedure Left;
begin
sum := sum - a[iLeft]; iLeft := iLeft + 1;
if (iLeft > iRight) then
begin iRight := iLeft; sum := a[iLeft]; end;
end;
procedure Right;
begin iRight := iRight + 1; sum := sum + a[iRight]; end;
procedure Update;
begin
if (LMin > iRight - iLeft + 1) then
begin iMin := iLeft; LMin := iRight - iLeft + 1; end;
Left;
end;
procedure XuLi;
begin
iLeft := 1; iRight := iLeft;
LMin := n + 1; sum := a[1];
repeat
if (sum = k) then Update
else if (sum < k) then Right
else { sum > k } Left;
until (iRight > n);
if (LMin = n+1) then LMin := 0;
end;

81
procedure Ghi;
begin
assign(g,gn); rewrite(g); writeln(g,iMin,bl,LMin); close(g);
end;
BEGIN
Doc; XuLi; ghi;
END.
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao2 {
class TongDoan {
const string fn = "TDoan.inp";
const string gn = "TDoan.out";
static public int n; // n - so phan tu
static public int k; // Tong can chon
static public int sum; // tong hien co
static public int ileft, iright; // hai dau cua so
static public int imin, lmin;
static public int [] a;
static void Main(string[] args) {
Doc(); XuLi(); Ghi(); XemKetQua();
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void XemKetQua() {
Console.WriteLine("\n Input: "+fn);
Console.WriteLine(File.ReadAllText(fn));
Console.WriteLine("\n Output: "+gn);
Console.WriteLine(File.ReadAllText(gn));
}
static public void XuLi(){
ileft = 0; iright = ileft;
sum = a[ileft]; lmin = n + 1;
while (iright < n)
if (sum == k) Update();
else if (sum < k) Right();
else /* s > k */ Left();
++imin;
}
static public void Update() {
if (lmin > iright - ileft + 1)
{ imin = ileft; lmin = iright - ileft + 1; }
Left();
}
static public void Left(){
sum -= a[ileft++];
if (ileft > iright)
{ iright = ileft; sum = a[ileft]; }
}
static public void Right() { sum += a[++iright]; }
static public void Doc(){
int[] v =
Array.ConvertAll(((File.ReadAllText(fn))).Split(

82
new char[] { ' ', '\t', '\r', '\n' },
StringSplitOptions.RemoveEmptyEntries),
new Converter<string, int>(int.Parse));
int j = 0; n = v[j++]; k = v[j++];
a = new int[n + 1]; a[n] = 0;
for (int i = 0; i < n; ++i) a[i] = v[j++];
}
static public void Ghi() {
if (lmin == n + 1) File.WriteAllText(gn, "0");
else
File.WriteAllText(gn,imin.ToString()+" "+lmin.ToString());
}
} // TongDoan
} // SangTao2
Bi 2.11 on khng gim di nht
Dijkstra E.
Cho dy gm N s nguyn. Tm on khng gim c chiu di ln nht.

D liu vo: tp vn bn MDOAN.INP
Dng th nht: s t nhin N, 1 s N s 20000.
T dng th hai tr i: cc phn t ca dy.
D liu ra: tp vn bn MDOAN.OUT
Cha mt dng duy nht gm hai s t nhin d ch
s u on v L s phn t trong on (chiu di
on).
Trong cc tp, d liu trn cng dng cch nhau qua
du cch.
Th d trn cho ta on khng gim di nht bao gm 7 phn t bt u t phn t th t trong dy
(cc phn t c gch di):
1 5 5 1 3 3 3 5 7 9 1 2
Thut ton
y l bi d, ta c dn cc phn t t input file v so snh hai phn t lin tip nhau l x (phn t
c trc ti bc i) v y (phn t c sau ti bc i+1). Nu y < x th coi nh kt thc mt an khng
gim, ta cp nht ghi nhn li on khng gim di nht. Cc bin tng th trong chng trnh c
dng nh sau:
MaxLen chiu di ca on khng gim di nht hin tm c,
imax - ch s u tin ca on khng gim di nht hin tm c,
ileft ch s u tin ca on khng gim ang xt.
phc tp: c N.
(* Pascal *)
(****************************************
MDOAN - Doan tang dai nhat
****************************************)
program MDoan;
uses crt;
const
bl = #32; fn = 'MDOAN.INP'; gn = 'MDOAN.OUT';
var f,g: text;
MDOAN.INP MDOAN.OUT

12
1 5 5 1 3
3 3 5 7 9
1 2

4 7



83
n: integer;
a: mw1;
iLeft, imax: integer;
MaxLen: integer;
procedure Update(i: integer);
begin
if (MaxLen < i - iLeft) then
begin
MaxLen := i - iLeft;
imax := iLeft; ileft := i;
end;
iLeft := i;
end;
procedure XuLi;
var i, x, y: integer;
begin
assign(f,fn); reset(f); readln(f,n);
read(f,x);
iLeft := 1; MaxLen := 0;
for i := 2 to n do
begin
read(f,y);
if (y < x) then Update(i);
x := y;
end;
Update(n+1);
close(f);
end;
procedure Ghi;
begin
assign(g,gn); rewrite(g);
writeln(g,imax,bl,MaxLen);
close(g);
end;
BEGIN
XuLi; ghi;
END.
Trong phng n C# di y ta c ton b d liu vo mt mng a ri x l trn mng ny.
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao2 {
class DoanKhongGiam {
const string fn = "MDoan.inp";
const string gn = "MDoan.out";
static public int n; // n - so phan tu
static public int imax; // chi so dau cua doan max
static public int ileft; // chi so dau cua doan dang xet
static public int maxlen; // chieu dai max
static public int [] a;
static void Main(string[] args) {
Doc(); XuLi(); Ghi(); XemKetQua();
Console.WriteLine("\n Fini ");
Console.ReadLine();

84
}
static public void XemKetQua(): t vit
static public void XuLi() {
ileft = 0; maxlen = 0;
for (int i = 1; i < n; ++i)
if (a[i] < a[i-1]) Update(i);
Update(n);
}
static public void Update(int i) {
if (maxlen < i - ileft)
{ maxlen = i - ileft; imax = ileft; ileft = i; }
}
static public void Doc(): t vit
static public void Ghi() {
File.WriteAllText(gn, imax.ToString() + " " +
maxlen.ToString()); }
} // DoanKhongGiam
} // SangTao2
Bi 2.12 on n iu di nht
Dijkstra E.
Cho dy gm N s nguyn. Tm on n iu (khng gim hoc khng tng) c chiu di ln nht.

D liu vo: tp vn bn DONDIEU.INP
Dng th nht: s t nhin N, 1 s N s 20000.
T dng th hai tr i: cc phn t ca dy.
D liu ra: tp vn bn DONDIEU.OUT
Cha mt dng duy nht gm hai s t nhin d ch
s u on v L s phn t trong on (chiu di
on).
Trong cc tp, d liu trn cng dng cch nhau qua
du cch.
Thut ton


Edsger Wybe Dijkstra (1930-2002)
Sinh nm 1930 ti Rotterdam, Holland.
1948-1956 hc Ton v Vt l l thuyt
ti i hc Leyden. 1952-1962 nghin
cu ti Trung tm Ton hc Amsterdam.
1962-1973 Gio s Ton ti i hc Bch
khoa Eindhoven, Holland v i hc
Texas Austin. Dijkstra l mt trong nhng
ngi i tin phong trong lnh vc lp
trnh, ngi khi xng v t nn mng
cho nguyn l lp trnh cu trc.
DONDIEU.INP DONDIEU.OUT

12
1 5 5 1 3
3 3 5 7 9
1 2

4 7



85
Edsger Wybe Dijkstra
(photo 2002 Hamilton
Richards)


Nhn xt:
on c 1 phn t l on n iu (tng, gim),
on gm mt dy lin tip cc phn t bng nhau l on n iu (tng, gim).
Ta dng hai bin m cc phn t tng hoc bng nhau lin tip, dt v m cc phn t gim hoc
bng nhau lin tip, dg. Nu a
i
= a
i1
ta tng ng thi dt v dg 1 n v. Nu a
i
> a
i1
ta tng dt thm 1 n
v v t li dg = 1. Nu a
i
< a
i1
ta tng dg thm 1 n v v chnh li dt = 1. Sau mi bc ta cp nht on
n iu di nht tm c. Chng trnh Pascal c v x l trc tip file input, chng trnh C# c ton
b d liu vo mng ri x l trn mng.
phc tp: c N.
Cc bin tng th:
n: s lng phn t,
dt: m s phn t trong dy tng,
dg: m s phn t trong dy gim.
iMax: ch s u ca on n iu di nht,
MaxLen: chiu di (s phn t) ca on n iu di nht.
(* Pascal *)
program DonDieu;
uses crt;
const
bl = #32; fn = 'DONDIEU.INP'; gn = 'DONDIEU.OUT';
var f,g: text;
n: integer;
dt,dg: integer;
iMax, MaxLen: integer;
function Max(a,b,c: integer): integer;
begin
if (a < b) then a := b; { a = Max(a,b) }
if (a > c) then Max := a
else Max := c;
end;
procedure XuLi;
var i,m,x,y: integer;
begin
assign(f,fn); reset(f);
readln(f,n); read(f,x);
dt := 1; dg := 1;
MaxLen := 1; iMax := 1;
for i := 2 to n do
begin
read(f,y);
if (y = x) then
begin dt := dt + 1; dg := dg + 1; end
else if (y > x) then
begin dt := dt + 1; dg := 1; end
else { y < x }
begin dg := dg + 1; dt := 1; end;

86
m := Max(MaxLen, dt, dg);
if (m > MaxLen) then
begin MaxLen := m; iMax := i - MaxLen + 1; end;
x := y;
end;
close(f);
end;
procedure Ghi;
begin
assign(g,gn); rewrite(g);
writeln(g, iMax, bl, MaxLen); close(g);
end;
BEGIN
XuLi; Ghi;
END.
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao2 {
class DonDieu {
const string fn = "DonDieu.inp";
const string gn = "DonDieu.out";
static public int n; // n - so phan tu
static public int imax; // chi so dau tien cua doan max
static public int maxlen; // chieu dai max
static public int [] a;
static void Main(string[] args) {
Doc(); XuLi(); Ghi(); XemKetQua();
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void XemKetQua(): t vit
static public void XuLi(){
imax = 0; maxlen = 1;
int dt = 1, dg = 1;
int m;
for (int i = 1; i < n; ++i){
if (a[i] == a[i - 1]) { ++dt; ++dg; }
else if (a[i] < a[i - 1]) { dt = 1; ++dg; }
else /* a[i] > a[i-1] */ { ++dt; dg = 1; }
m = Max(maxlen, dt, dg);
if (maxlen < m)
{ maxlen = m; imax = i - maxlen + 1; }
}
}
static public int Max(int a, int b, int c){
if (a < b) a = b; // a = Max(a,b)
return (a > c) ? a : c;
}
static public void Doc(): t vit
static public void Ghi(): t vit
} // DonDieu
} // SangTao2

87
Bi 2.13 Ly tha 2, 3 v 5
Dijkstra E.
Vi mi gi tr N cho trc hy sinh N s u tin theo trt t tng dn l tch cc ly tha ca 2, 3
v 5.

D liu vo: tp vn bn LUYTHUA.INP
Cha s t nhin N, 1 s N s 1000.
D liu ra: tp vn bn LUYTHUA.OUT
N s tm c, mi dng mt s.
Thut ton
Gi S l tp cc s cn tm. Ta c
(i) 1 e S
(ii) Nu x e S th 2x, 3x, 5x e S.
Gi s cc phn t trong S c sp tng v ta
tm c phn t th i. Ta k hiu S(i) = { a
1
, a
2
,,a
i
}.
tm phn t th i+1 ta nhn xt
a
i+1
= Min { 2x, 3y, 5z | x, y, z e S(i), 2x > a
i
, 3y >
a
i
, 5z > a
i
}
Ta s dng 3 bin i2, i3, i5 ghi nhn cc ch s
trong S sao cho a
i2
= x, a
i3
= y v a
i5
= z. Cc bin a[1], i2,
i3 v i5 c khi tr 1.

Khi hm Next(i) sinh phn t st sau phn t A[i] s nh sau:
function Next(i: integer): integer;
begin
while (a[i2] * 2 <= a[i]) do i2 := i2 + 1;
while (a[i3] * 3 <= a[i]) do i3 := i3 + 1;
while (a[i5] * 5 <= a[i]) do i5 := i5 + 1;
Next := Min(a[i2]*2, a[i3]*3, a[i5]*5);
end;
(* Pascal *)
(***************************************
LUY THUA cua 2, 3, 5
*************************************)
program LuyThua;
uses crt;
const bl = #32; mn = 1001; fn = 'LUYTHUA.INP'; gn = 'LUYTHUA.OUT';
type ml1 = array[0..mn] of longint;
var f,g: text;
n: integer;
a: ml1;
procedure Doc: t vit;
function Min(a,b,c: longint): t vit;
function Next(i: integer): t vit;
procedure Sinh;
var i: longint;
begin
assign(g,gn); rewrite(g);
LUYTHUA.INP LUYTHUA.OUT

12

1
2
3
4
5
6
8
9
10
12
15
16


88
a[1] := 1; writeln(g,1);
i2 := 1; i3 := 1; i5 := 1;
for i := 2 to n do
begin
a[i] := Next(i-1);
writeln(g,a[i]);
end;
close(g);
end;
BEGIN
Doc; Sinh;
END.
// C#
using System;
using System.IO;
namespace SangTao2 {
/*-------------------------------------------*
Luy thua 2, 3, 5
* ------------------------------------------*/
class LuyThua235 {
const string fn = "LuyThua.inp";
const string gn = "LuyThua.out";
static public int n; // so luong phan tu
static public int[] a;
static void Main(){
Doc(); Sinh(); Ghi(); XemKetQua();
Console.WriteLine("\n fini");
Console.ReadLine();
} // Main
static public void Doc()
{ n = int.Parse(File.ReadAllText(fn).Trim()); }
static public void Sinh(){
a = new int[n];
int i2 = 0, i3 = 0, i5 = 0; a[0] = 1;
int n1 = n-1;
for (int i = 0; i < n1; ++i){ // Next
while (a[i2] * 2 <= a[i]) ++i2;
while (a[i3] * 3 <= a[i]) ++i3;
while (a[i5] * 5 <= a[i]) ++i5;
a[i + 1] = Min(a[i2] * 2, a[i3] * 3, a[i5] * 5);
}
}
static public int Min(int x, int y, int z) : t vit
static public void Ghi(){
StreamWriter g = new StreamWriter(gn);
for (int i = 0; i < n; ++i) g.WriteLine(a[i]);
g.Close();
}
static void XemKetQua(): t vit
} // LuyThua235
} // space



89
Chng 3
Tr chi

Cc bi ton tr chi kh a dng v thng l kh.
Chng ta xt loi tr chi th nht vi cc ga thit sau y:
1. Tr chi gm hai u th l A v B, lun phin nhau, mi ngi i mt nc. Ta lun gi thit
u th i trc l A.
2. Hai u th u chi rt gii, ngha l c kh nng tnh trc mi nc i.
3. u th no n lt mnh khng th i c na th chu thua v vn chi kt thc.
4. Khng c th ha, sau hu hn nc i s xc nh c ai thng, ai thua.
Gi thit chi gii nhm trnh cc trng hp n may, tc l cc trng hp do i phng h
hnh m i lc nc. iu ny tng ng vi gi thit c hai u th u c th tnh trc mi nc i
(vi loi tr chi hu hn) hoc c hai u th u bit cch i tt nht. tin trnh by chng ta gi cc
tr chi loi ny l chi c, mi th ca bn c l mt tnh hung vi d liu c th, ta thng gi l mt
cu hnh.
Cc bi ton tin lin quan n loi tr chi ny thng l:
- Lp trnh xc nh vi mt th c cho trc th ngi i trc (u th A) s thng hay thua.
- Lp trnh my tnh chi vi ngi. D nhin chng trnh bn lp ra l dnh cho my tnh.
- Lp trnh hai my tnh chi vi nhau.
Vi loi tr chi ny c mt heuristic mang tnh ch o sau y:
Trc ht cn xc nh c mt tnh cht T tha cc iu kin sau y:
a) Th thua cui cng tha T,
b) Mi nc i lun lun bin T thnh V = not T,
c) Tn ti mt nc i bin V thnh T.
Tnh cht T c gi l bt bin thua ca tr chi.
Vic chuyn th X thnh not X thng c gi l lt th X. Cc qui tc a - c c th pht biu li
nh sau:


90
T c gi l bt bin thua nu
a') Th thua cui cng tha T,
b') Mi nc i t T u lt T thnh V,
c') Tn ti mt nc i lt V thnh T.
u th no c cch y u th khc vo th
thua T th u th s thng.
u th no khng th y u th khc vo th
thua T th u th s thua.
Nc i y c hiu l nc i hp l tc l nc i tun th cc qui nh ca tr chi, th d
"xe lin, pho cch" trong c tng qui nh rng qun xe c th "n" trc tip cc qun ca i phng
nm trn ng i ca n, cn qun pho th phi "n" qua mt qun m.
im kh nht ca loi ton ny l xc nh bt bin thua.
Bi 3.1. Bc si A
Trn bn c mt ng si N vin, hai u th A v B ln lt i, A i nc u tin. Mi nc i
u th buc phi bc t 1 n M vin si khi bn. u th no n lt mnh khng i ni th thua. C
hai u th u chi rt gii. Vi hai s N v M cho trc hy cho bit A thng (ghi 1) hay thua (ghi 0).
Ta th chi vi M = 3 v vi d liu ban u N = 1, 2 , tnh nc i cho u th A bn hy k
mt bng gm 2 dng. Dng th nht l cc gi tr ca N. Dng th hai c ghi 0 ng vi tnh hung A
thua v 1 cho tnh cho trng hp A thng, nu A l u th i nc u tin.

M = 3 N = 0 1 2 3 4 5 6 7 8 9 10 11 12 13
A thng (1) hay thua (0)? 0 1 1 1 0 1 1 1 0 1 1 1 0 1
Cch i: s vin cn bc chc thng # 1 2 3 # 1 2 3 # 1 2 3 # 1
Mt vi tnh hung cho bi Bc si A, M = 3; # - u hng/bc tm 1 vin

Th d, vi M = 3 cho trc v c nh, A l u th i trc, ta c
N = 0 l mt th thua, v A khng c cch i.
N = 1 l mt th thng, v A s bc 1 vin, B ht cch i.
N = 2 l mt th thng, v A s bc 2 vin, B ht cch i.
N = 3 l mt th thng v A s bc 3 vin, B ht cch i.
N = 4 l mt th thua, v d A bc 1, 2, hoc 3 vin u dn n cc th thng l 3, 2, 1
Lm th no xc nh c bt bin ca tr chi? Phng php n gin l t duy Nhn - Qu
hay l lp lun li. C th l, nu bit kt qu l Q ta hy gng tm nguyn nhn N sinh ra Q. Ta rng,

Qui tc xc nh th thng / thua
T mt th X ang xt,
- nu tm c mt nc i dn n th thua T th X s l th thng V, v
- nu mi nc i t X u dn n th thng th X s l th thua T.

Trc ht ta s tm mt th thua nh nht ca cuc chi hay cn gi l th thua kt hoc th thua
cui cng, v u th no gp th ny u phi u hng v vn chi kt thc.
D thy th thua kt s l N = 0: Ht si, khng th thc hin c nc i no.

91
Vy trc , nhng nc i no c th dn n th thua T(N = 0)?
Do mi u th ch c php bc 1, 2 hoc 3 vin nn cc th thng V trc ch c th l N = 1,
2, hoc 3. Ta vit
T(N = 0) V(N = 1 | 2 | 3) T(N = ?)
trong T l k hiu cho th thua, V l k hiu cho th thng.
Ta th xc nh th thua T(N = ?). D thy vi N = 4 th mi cch bc 1, 2 hoc 3 vin si u dn
n th thng V(N = 3 | 2 | 1). Ta c,
T(N = 0) V(N = 1 | 2 | 3) T(N = 4)
n y ta c th d on bt bin thua s l N = 4k, cho trng hp M = 3, hoc tng qut hn, N
= k(M+1), k > 0.
Vy bt bin thua l:
T: S vin si trong ng l bi ca M+1: N = k(M+1), k > 0.
Ta s chng minh rng nu N = k(M+1), k = 0, 1, 2,th ngi i trc (l A) lun lun thua.
Trc ht rng nu u th A gp s si l bi ca M+1 th vi mi cch i ca A s si cn li
s khng phi l bi ca M+1. Tht vy, mun bo ton tnh cht l bi ca M+1 th A buc phi bc mt
bi no ca M+1, y l iu khng c php v vi phm lut chi.
Gi s N = k(M+1), k > 1. Gi s si A bc l s. Ta c, do 1 s s s M nn B s bc u = (M+1)s
vin si v do s si cn li s li l N = k(M+1) s ((M+1) s) k(M+1)(M+1) = (k1)(M+1). y
l mt bi ca (M+1).
Nu s si l bi ca M+1 th vi mi cch i hp l, s si cn li s khng cn l bi ca M+1.
Nu s si khng phi l bi ca M+1 th lun lun tn ti mt cch i chnh s si tr thnh bi ca
M+1.
Kt lun Bi Bc si A
Nu s si N = k(M+1), k > 0
th u th no i trc s thua.


Vi gi thit A l u th i trc, ta vit hm Ket(N,M) cho ra gi tr 1 nu A thng, ngc li
hm cho gi tr 0 nu A thua. Hm c hai tham bin: N l s vin si trong ng, M l gii hn s vin si
c php bc. Hm n thun ch kim tra xem tr N c l bi ca M+1 hay khng.
(* Pascal *)
function Ket(N,M: integer): integer;
begin
if (N mod (M+1) = 0) then ket := 0 else Ket := 1;
end;
Hm CachDi(N,M) di y m nhn chc nng hng dn ngi chi chn mt cch i. Trc
ht cn kim tra xem th ang xt l thng hay thua. Nu l th thua v cn si th bc 1 vin nhm ko
di thi gian thua. Nu l th thng th bc s si d s si cn li s l bi ca (M+1).
(* Pascal *)
function CachDi(N,M: integer): integer;
var r: integer;
begin
r := N mod (M+1);
if r = 0 then { thua }
begin
if N = 0 then CachDi := 0 else CachDi := 1;
exit;
end;

92
CachDi := r;
end;
// C#
static int Ket(int n, int m) { return (n%(m+1) == 0) ? 0 : 1;}
static int CachDi(int n, int m) {
int r = n % (m+1);
if (r == 0) // thua
return (n == 0) ? 0 : 1;
return r;
}
Bi 3.2. Bc si B
Cho ng si N vin, hai u th A v B ln lt i, A i nc u tin. Mi nc i u th c
php bc t 1 n M vin si. u th no thc hin nc i cui cng th thua. C hai u th u chi
rt gii. Vi hai s N v M cho trc hy cho bit A thng (ghi 1) hay thua (ghi 0).
Ta nhn thy bi ny ch khc bi Bc si A iu kin thua: ai bc qun cui cng s thua.
Chc chn l bn s c th xc nh ngay c bt bin thua ca tr chi ny l
N = k(M+1) + 1, k > 0. Tuy nhin, hnh thnh k nng pht hin lut chi cho cc bi ton kh hn sau
ny, bn hy gng thc hin cc bc tm kim theo cc s sau y:
S 1: Th vi vi d liu ban u: M = 3; N = 1, 2,

M = 3 N = 1 2 3 4 5 6 7 8 9 10 11 12 13
A thng (1) hay thua (0)? 0 1 1 1 0 1 1 1 0 1 1 1 0
Cch i: s vin cn bc
chc thng.
# 1 2 3 # 1 2 3 # 1 2 3 #
Mt vi tnh hung cho bi Bc si B, M = 3; # - u hng/bc tm 1 vin

S 2: Tnh hai hai th thua lin tip theo lp lun li (Nhn - qu).

S tnh hai th thua lin tip
Bc 1 Xc nh th thua nh nht: T (N = 1)
Bc 2 Xc nh cc th thng V dn n T: T V c mt nc i dn n T.
T(N=1) V(N = 2 | 3 | 4)
Bc 3 Xc nh th thua T dn n V: Mi cch i t T u ri vo V.
T(N=1) V(N = 2 | 3 | 4) T(N=5)
Bc 4 Tng qut ha, xy dng v chng minh cng thc xc nh bt bin thua:
N = k(M+1)+1, k > 0

S 3: Tng qut ha (Chi tit ha Bc 4 trong S 2). Trong s 3 di y ta k hiu X(k)
l s vin si ti th X xt trong bc k = 0, 1, 2... X c th l th thng V hoc th thua T, ch rng bc
k c xt theo qu trnh lp lun li ch khng xt theo din tin ca tr chi.

93
Bc 4. Tng qut ha
Bc 4.1 Th thua nh nht: T(0) = 1.
Bc 4.2 Gi thit th thua ti bc k l T(k) (s vin si ngi i trc thua).
Bc 4.3 Xc nh cc th thng V(k) dn n T(k): C mt cch i trn bn cn T(k) vin si.
T(k) V(k) = T(k) + d; 1 s d s M.
Bc 4.4 Xc nh th thua T(k+1) dn n V(k): Mi cch i t T(k+1) u ri vo V(k) = T(k) + d;
1 s d s M:
T(k) V(k) = T(k) + d; 1 s d s M T(k+1) = Max {V(k)}+1 = T(k)+(M+1)
Bc 4.5 Chng minh cng thc T(k) bng qui np: T(k) = k(M+1)+1
D on cng thc: Ta c, theo cng thc thu c Bc 4.4, T(k+1) = T(k)+(M+1),
T(0) = 1;
T(1) = T(0)+(M+1) = 1+(M+1);
T(2) = T(1)+(M+1) = 1+(M+1)+(M+1) = 2(M+1)+1;
T(3) = T(2)+(M+1) = 2(M+1)+1+(M+1) = 3(M+1)+1;
...
D on: T(k) = k(M+1)+1.
Chng mnh bt bin thua: Nu s si trong ng l T(k) = k(M+1)+1, k > 0 th ai i trc s thua.
C s qui np: vi k = 0 ta c T(0) = 0.(M+1)+1 = 1. y l th thua nh nht.
Gi s vi k > 1 ta c th thua l T(k) = k(M+1)+1. Ta chng minh rng T(k+1) = (k+1)(M+1)+1 s
l th thua tip theo v gia hai th thua ny l cc th thng. Tht vy, v T(k) l th thua nn cc th c
dng V(k) = T(k)+d, 1 s d s M s u l th thng. T y suy ra th thua tip sau phi l T(k+1) =
T(k)+M+1 = k(M+1)+1+(M+1) = (k+1)(M+1)+1.

Kt lun Bi Bc si B
Nu s si N = k(M+1)+1, k > 0
th u th no i trc s thua.

Ta cng c th s dng hm f(N) xc nh xem vi ng si c N vin th ngi i trc s thng
(f(N) = 1) hay thua (f(N) = 0). Ta c, f(1) = 0 v vi 1 vin si th ai bc vin s thua. Gi s f(N) = 0.
D thy, khi f(N+d) = 1 vi 1 s d s M, v ch cn bc d vin si l dn n th thua. Tip n
f(N+(M+1)) = 0 v vi mi cch bc s vin si, 1 s s s M i phng s bc tip u = (M+1)s s si
cn li l N vin ng vi th thua. T suy ra f(N) = 0 vi N = k(M+1)+1; cn li l f(N) = 1.
Hai hm Ket(N,M) v CachDi(N,M) vi N > 0 khi s nh sau.
(* Pascal *)
function Ket(N,M: integer): integer; {0: thua; 1: thang}
begin
if (N mod (M+1) = 1) then ket := 0 else Ket := 1;
end;
function CachDi(N,M: integer): integer;
var r: integer;
begin
r := N mod (M+1);
if (r = 1) then { thua: boc tam 1 vien }

94
CachDi := 1 else
if (r = 0)then CachDi := M
else CachDi := r-1;
end;
// C#
static int Ket(int n, int m)// 0: thua; 1: thang
{ return (n % (m+1) == 1) ? 0 : 1; }
static int CachDi(int n, int m) {
int r = n % (m+1);
if (r == 1) // thua, boc tam 1 vien
return 1;
else return (r == 0) ? m : r-1;
}
Bi 3.3. Bc si C
Cho ng si N vin, hai u th A v B ln lt i, A i nc u tin. Ti mi nc i, u th
buc phi bc ti thiu 1 qun, ti a na s qun trong ng. u th no n lt mnh khng i ni th
thua. C hai u th u chi rt gii. Cho bit A thng hay thua.
Ch :
Nu s qun l th bc na non,
ng no cn 1 qun th khng c cch bc ng , v 1 div 2 = 0 trong khi yu cu ca
lut chi l phi bc ti thiu 1 qun.
S 1: Th vi vi d liu ban u: N = 1, 2, 3,

N 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
A thng (1) hay thua (0)? 0 1 0 1 1 1 0 1 1 1 1 1 1 1 0 1
Cch i: s si cn bc
chc thng
# 1 # 1 2 3 # 1 2 3 4 5 6 7 # 1
Mt vi tnh hung cho bi Bc si C; # - u hng/bc tm 1 vin.

S 2: Kho st hai th thua lin tip theo lp lun li (Nhn - qu).

S tnh hai th thua lin tip
Bc 1 Xc nh th thua nh nht: T (N = 1)
Bc 2 Xc nh cc th thng V dn n T: T V c mt nc i dn n T.
T(N = 1) V(N = 2)
Bc 3 Xc nh th thua T dn n V: Mi cch i t T u ri vo V.
T(N = 1) V(N = 2) T(N = 3)
Bc 4 Tng qut ha, xy dng v chng minh cng thc xc nh bt bin thua:
N = 2
k
1, k > 1


95
S 3: Tng qut ha (Chi tit ha Bc 4 trong S 2). Trong s 3 di y ta k hiu X(k)
l s vin si ti th X xt trong bc k = 0, 1, 2, theo lp lun li t th thua nh nht tr i. X c th l
th thng V hoc th thua T.

Bc 4. Tng qut ha
Bc 4.1 Th thua nh nht: T(0) = 1.
Bc 4.2 Gi thit th thua T(k) c N vin si: T(k) = N.
Bc 4.3 Xc nh cc th thng V(k) dn n T(k): C mt cch i trn bn cn N vin si.
T(k) V(k) = N + d; 1 s d s N.
Bc 4.4 Xc nh th thua T(k+1) dn n V(k): Mi cch i t T(k+1) u ri vo V(k) = N + d;
1 s d s N.
T(k) V(k) = N + d; 1 s d s N T(k+1) = Max {V(k)} + 1 = N+N+1
Bc 4.5 Chng minh cng thc T(k) bng qui np: T(k) = 2
k
1.

Gi T(k) l th thua kho st ti bc th k. Ta c,
Th thua nh nht T(0) = 1: nu c 1 vin si th khng i ni: chu thua.
Gi s th thua ti bc th k l T(k) = N
Khi cc th thng dn n th T(k), theo lut chi s l V(k) = T(k)+d,
1 s d s T(k) v th thua tip sau phi l T(k+1) = T(k)+T(k)+1 = 2T(k)+1.
Tng hp li ta c
T(0) = 1,
T(1) = 2T(0)+1 = 2+1,
T(2) = 2T(1)+1 = 2(2+1) + 1 = 2
2
+2+1,
T(3) = 2T(2)+1 = 2(2
2
+2+1)+1 = 2
3
+2
2
+2+1.
...
p dng cng thc a
k+1
1= (a
k
+ a
k-1
+...+a+1) (a1) ta d on:
T(k) = 2
k
+ 2
k-1
+...+2+1 = (2
k+1
1)/(21) = 2
k+1
1.
Ta dng qui np ton hc chng minh rng T(k) = 2
k+1
1.
Vi k = 0, ta c T(0) = 2
1
1 = 2 1 = 1. Vy T(k) ng vi k = 0.
Gi s T(k) = 2
k+1
1. Ta chng minh T(k+1) = 2
k+2
1.
Ta c, T(k+1) = 2T(k)+1 = 2(2
k+1
1)+1 = 2
k+2
2+1 = 2
k+2
1, pcm.

Kt lun Bi Bc si C
Nu s si N c dng 2
k
- 1, k > 1 th u
th no i trc s thua.

Cc s dng 2
k
1 c gi l s Mersenne mang tn nh ton hc Php th k th XVII, ngi
u tin nghin cu chng.

96
Vi gi thit A l u th i trc, ta vit hm Ket(N) cho ra gi tr 1 nu A thng, ngc li hm
cho gi tr 0 nu A thua. Hm ch n thun kim tra xem N c phi l s Mersenne hay khng. Nu ng
nh vy th u th A s thua, ngc li l A thng.




Marin Mersenne (1588-1648) l con mt gia nh nng
dn Php. Lc u ng hc thn hc v trit hc, sau
chuyn sang nghin cu ton hc v m nhc. ng
li nhng kt qu l th v c s ton hc ca m
nhc, hnh hc v l thuyt s.

Ta rng N = 2
k
1 tng ng vi N+1 = 2
k
. V cc s nguyn trong my tnh u c biu
din di dng nh phn, nn tnh gi tr 2
k
ta ch vic dch s 1 qua tri k bit.
(* Pascal *)
function Ket(N : integer) : integer;
var m,n1: integer;
begin
n1 := N + 1; m := 1;
while (m < n1) do m := m shl 1;
{ m = 2
k
> n1 = N+1 ==> N s 2
k
-1 }
if m = n1 then Ket := 0 else Ket := 1;
end;
Hm CachDi di y s xc nh s si cn bc cho mi tnh hung. Trc ht hm kim tra xem
s si trong ng c phi l s Mersenne hay khng qua h thc N+1 = 2
k
? Nu N = 2
k
1 th ngi no i
s thua, do ta chn cch i chm thua nht bng vic bc 1 vin si. D nhin nu N = 1 th ta phi chu
thua bng cch gn CachDi = 0. Ta xt trng hp N khng phi l s Mersenne. Khi tn ti mt s
nguyn k tha 2
k
1 < N < 2
k+1
1. Ta cn bc bt s si chnh lch l s = N(2
k
1) s si cn li c
dng 2
k
1. Ta chng minh 1 s s s N/2, tc l cch i ny l hp l theo quy nh ca u bi. Tht vy,
do 2
k
1 < N nn s = N(2
k
1) > 1. Mt khc, nu s > N/2 tc l N(2
k
1) > N/2 th N/2 > 2
k
1 hay N >
2
k+1
2. T y suy ra N > 2
k+1
1 mu thun vi iu kin ca k. Vy ta phi c s s N/2.

(* Pascal *)
function CachDi(N : integer) : integer;
var m, n1: integer;
begin
n1 := N + 1; m := 1;
while (m < n1) do m := m shl 1;
{ m = 2
k
> n1 = N+1 ==> N s 2
k
-1 }

97
if m = n1 then { N = 2
k
- 1: Thua }
begin
if N = 1 then CachDi := 0
else CachDi := 1;
exit;
end;
{ m = 2
k
> N+1 }
m := m shr 1;
{ m = 2
k-1
< N+1 < 2
k
= 2m ==> m-1 < N < 2m-1 }
CachDi := N-m+1;
end;
// C#
static int Ket(int n) {
int m = 1,n1 = n + 1;
while (m < n1) m <<= 1;
// m = 2
k
> n1 = n+1 ==> n s 2
k
-1
Ket = (m == n1) ? 0 : 1;
}
static int CachDi(int n) {
int m = 1, n1 = n + 1;
while (m < n1) m <<= 1;
// m = 2
k
> n1 = n+1 ==> n s 2
k
-1
if (m == n1) // Thua
return (n == 1) ? 0 : 1;
// m = 2
k
> n+1
m >>= 1;
// m = 2
k-1
< n+1 < 2
k
= 2m ==> m-1 < n < 2m-1
return n-m+1;
}
Bi 3.4. Chia on
Dng pht biu khc ca Bi Bc si C
Cho mt on thng trn trc s di N n v vi cc im chia nguyn. Hai bn ln lt thc hin
thao tc sau y: Ct on thng ti mt im nguyn nm trong on thu c 2 on con sau vt
i on ngn, trao on di cho ngi kia. Nu hai on bng nhau th vt i mt on ty . Bn no n
lt mnh khng th thc hin c thao tc trn th thua. Hy cho bit bn i trc thng hay thua. Gi
thit rng hai bn u chi rt gii.
Bi 3.5. Bc si D
Cho 2 ng si vi s vin si ln lt l N v M vin. Hai ngi chi A v B, A lun i trc. Lt
chi: Chn ng ty , bc ti thiu 1 vin v ti a c ng. u th no n lt mnh m khng i ni
th thua. Hy cho bit A thng hay thua. Gi thit rng hai u th u chi rt gii.

Thut ton
Bi ny kh d gii.
Bt bin thua cho Bi Bc si
D
S si ca hai ng bng nhau.


98
Nu s si ca hai ng khc nhau th A l u th i trc s cn bng hai ng bng cch chn
ng ln ri bc bt s si chnh lch s si ca hai ng tr thnh bng nhau. Khi B i th s bin hai
ng thnh khc nhau, n lt A li cn bng hai ng
Ta cng d dng vit c hm kt nh sau:
(* Pascal *)
function Ket(N,M : integer) : integer;
begin
if N = M then Ket := 0 else Ket := 1;
end;
Th tc CachDi di y s xc nh ng v s si cn bc cho mi tnh hung. Hm nhn vo l
N - s lng si ca ng th nht v M - s lng si ca ng th hai v cho ra hai gi tr: D - ng si
cn chn v S - s vin si cn bc ti ng . Nu N = M, tc l gp th thua th nh bc 1 vin ti ng
ty chn, mt cch ngu nhin. Ta qui c D = 0 l tnh hung chu thua, tc l khi c hai ng ht si.
(* Pascal *)
procedure CachDi(N, M : integer; var D,S : integer);
{ Dong 1: N vien, Dong 2: M vien soi }
begin
if N = M then { Se Thua }
begin
if N = 0 then D := 0 { Het soi: dau hang }
else
begin { Keo dai cuoc choi }
S := 1; { boc 1 vien }
D := random(2)+1;{tai 1 dong tuy chon}
end;
exit;
end;
{ Tinh huong thang }
if N > M then D := 1 else D := 2; { Chon dong nhieu soi }
S := abs(N-M); { Boc so soi chenh lech }
end;
// C#
static int Ket(int n, int m) {
// ng 1: n vin; ng 2: m vin
return (n == m) ? 0 : 1;
}
static void CachDi(int n, int m, out int s, out int d) {
Random r = new Random();
if (n == m) { // thua
if (n == 0) d = 0;
else {
s = 1;
d = r.Next(2) + 1;
}
}
// n != m: thang
d = (n > m) ? 1 : 2;
s = (d == 1) ? (n m) : (m n);
}
Bn th ngh
Tnh hnh s ra sao nu ta xt li bi ny vi iu kin thu nh sau: u th bc nhng qun cui
cng cn trn bn s thua?

99
Bi 3.6. Bc si E
Cho 2 ng si vi s vin si ln lt l N v M vin. Hai ngi chi A v B, A lun i trc. Lt
chi: Chn ng ty , bc ti thiu 1 vin v ti a c ng. u th no bc nhng qun cui cng cn
trn bn s thua. Hy cho bit A thng hay thua. Gi thit rng hai u th u chi rt gii.
Thut ton
D thy khi mt trong hai ng ch cn 1 vin si, ng th hai c si th ai i trc s thng, v
ngi ch vic bc ht ng si cn li. Ta xt trng hp N, M > 1. Vi trng hp ny ta s dng bt
bin thua T(N=M) v tm cch cn bng hai ng si.
M




N

O O O O O O


1 0 1 1 1 1
C
0 1 1 1 1 1
C
1 1 0 1 1 1
C
1 1 1 0 1 1

1 1 1 1 0 1
C
1 1 1 1 1 0

Gi A l u th i trc, ta k hiu f(N,M) l hm hai bin cho gi tr 1 nu A thng, v gi tr 0
nu A thua, N v M l s si trong hai ng. D thy f l hm i xng, tc l f(N,M) = f(M,N) v trt t
ca hai ng si khng quan trng. tnh tr ca f ta s dng ma trn hai chiu f, cc dng ng vi gi tr
N, cc ct ng vi gi tr M. Ma trn ny i xng qua ng cho chnh, do ta lun gi thit l N s M
v s ln lt in tr theo cc dng, ti mi dng N ta bt u in tr t cc ct M > N tr i. Ta c nhn
xt th v sau y:
* f(1,0) = f(0,1) = f(N,N) = 0, N > 1,
* Cc gi tr cn li trong bng u bng 1.
Hm Ket v th tc CachDi s nh sau.
Bt bin thua cho bi Bc si
E
1. N = M > 1, hoc
2. (0, 1), (1, 0)

function Ket(N,M : integer) : integer;
begin
if (N + M = 1) or ((N = M) and (N > 1))
then Ket := 0 else Ket := 1;
end;
Vi th tc CachDi cho tnh hung thng ta phi xt kh nhiu trng hp.
Trng hp 1. Ch cn mt ng: ta bc ng kia, bt li mt vin.
Trng hp 2. C mt ng cha duy nht 1 vin si: ta bc ht ng kia.
Hai trng hp 1 v 2 c th gp lm 1 nh sau:
Trng hp 1&2. Nu mt ng cn khng qu 1 vin si th bc ng kia s si N+M1.
Trng hp 3. Cn bng s si hai ng bng cch bc s si chnh lch.

100
rng trong c 3 trng hp thng v c trng hp thua ta u chn ng c nhiu si hn
bc.
procedure CachDi(N,M : integer; var D,S : integer);
begin
{ Chon dong nhieu soi }
if N > M then D := 1 else D := 2;
if (N + M = 1) or ((N = M) and (N > 1))then
begin { Se Thua }
S := 1; { boc 1 vien }
exit;
end;
{ Cac tinh huong thang }
if (N < 2) or (M < 2) then S := N+M-1
else S := abs(N-M);
end;
// C#
static int Ket(int n, int m) {
return (n + m == 1 || (n == m && n > 1)) ? 0 : 1;
}
static void CachDi(int n, int m, out int d, out int s) {
d = (n > m) ? 1 : 2;
if (n + m == 1 || (n == m && n > 1)) { // se thua
s = 1; // boc 1 vien
return;
}
s = (n < 2 || m < 2) ? (n+m-1) : Math.Abs(n - m);
}

Bi 3.7. Bc si F
Cho 2 ng si vi s vin si ln lt l N v M vin, N, M > 1. Hai ngi chi A v B, A lun i
trc. Lt chi: Chn ng ty , bc ti thiu 1 vin v ti a na s vin ca ng. u th no n
lt mnh m khng i ni th thua. Hy cho bit A thng hay thua. Gi thit rng hai u th u chi
rt gii.
Thut ton
Mi xem ta thy rng bt bin thua cho bi ny cng l N = M. D on ca bn gn ng v N = M
ch l mt trng hp c bit ca bt bin thua. D thy, nu N = M =1 th ht cch i. Nu N = M > 1 v
A i trc th B ch vic cn bng li s si ca hai ng l chc thng. Vy N = M l mt iu kin thua
(cho ngi i trc).
lp bng tnh tr ca hm f(N,M) ta cng nhn xt rng hm ny i xng, tc l f(N,M) =
f(M,N) v trt t ca cc ng si l khng quan trng. Cng chnh v f(N,M) l hm i xng nn ta ch
cn tnh tr ca f(N,M) vi N s M ri ly i xng qua ng cho chnh ca bng tr. Vi mi N cho trc
ta ln lt in tng dng N ca bng vi M = N, N+1, N+2, Theo nhn xt trn ta c ngay f(N,N) = 0
vi mi N. T th thua ny ta thy ngay f(N,N+d) = 1 vi mi d = 1,2,N v t cc th ny ta c th bc d
vin t ng th hai (ng c M=N+d vin) dn n th thua f(N,N). T y suy ra th thua tip theo s
l f(N,N+N+1) = f(N,2N+1). Tng t, th thua tip sau th ny phi l f(N,2(2N+1)+1) = f(N,2
2
N+2+1).
Tng qat ha ta thu c kt qu sau:
Nu ng si th nht c N vin th cc th thua s c dng f(N,M) vi M = 2
k
N+2
k

1
++2+1 =
2
k
N+(2
k

1
++2+1). p dng cng thc
2
k
1 = (21)(2
k

1
+2
k

2
++2+1) = 2
k

1
+2
k

2
++2+1
ta thu c M = 2
k
N+2
k
1 hay M+1 = 2
k
(N+1).
Vy

101
Bt bin thua cho Bi Bc si F
S si trong hai ng tha h thc
(N+1) = 2
k
(M+1), k > 0 (*)
T h thc (*) ta suy ra N = M l trng hp ring khi k = 0.
Hm Ket v th tc CachDi khi s nh sau.
rng cc s nguyn trong my tnh c biu din di dng nh phn nn gi tr 2
k
tng ng vi
ton t dch tri 1 k bit, 1 shl k.
function Ket(N,M : integer) : integer;
var N1,M1,t: integer;
begin
N1 := N+1; M1 := M+1;
if N1 < M1 then
begin
t := N1; N1 := M1; M1 := t;
end; { N1 > M1 }
while M1 < N1 do M1 := M1 shl 1; { 2*M1 }
if (M1 = N1) then Ket := 0 else Ket := 1;
end;
Vi th tc CachDi cho tnh hung thua th A nh bc 1 vin ng nhiu si. Trong trng hp
thng ta cng chn ng nhiu si bc bt S vin sao cho s si gia hai ng tha h thc (*). Ta tnh
S nh sau. Gi s N > M v k l s nguyn u tin tha h thc N+1 < 2
k
(M+1). Khi , do iu kin
thng nn ta phi c 2
k

1
(M+1) < N+1 < 2
k
(M+1) . Vy s si chnh lch cn bc bt ng nhiu si s l
S = N+12
k

1
(M+1). Ta chng minh rng 1 s S s N/2. Tht vy, v 2
k

1
(M+1) < N+1 nn S =
N+12
k

1
(M+1) > 1. Mt khc, nu S > N/2 th 2S > N hay 2N+22
k
(M+1) > N. T y rt ra N+1 >
2
k
(M+1)1, hay N+1 > 2
k
(M+1), mu thun vi gi thit v k.
procedure CachDi(N,M : integer; var D,S : integer);
var N1,M1,t: integer;
begin
{ N = M = 1: dau hang }
if (N = M) and (N = 1) then
begin
D := 0; S := 0;
exit;
end;
{ Chon dong nhieu soi }
if N > M then D := 1 else D := 2;
N1 := N+1; M1 := M+1;
if N1 < M1 then
begin
t := N1; N1 := M1; M1 := t;
end; { N1 > M1 }
while M1 < N1 do M1 := M1 shl 1; { 2*M1 }
if (M1 = N1) then { Thua }
begin { Se Thua }
S := 1; { boc 1 vien }
exit;
end;
{ Cac tinh huong thang }
M1 := M1 shr 1;
S := N1-M1;
end;


102
// C#
static int Ket(int n, int m) {
if (n < m) {
int t = n; n = m; m = t;
} // n >= m
int n1 = n + 1, m1 = m + 1;
while (m1 < n1) m1 <<= 1;
return (m1 == n1) ? 0 : 1;
}
static void CachDi(int n, int m, out int d, out int s){
// n = m = 1: dau hang
if (n == m && n == 1){
s = d = 0;
return;
}
// Chon dong nhieu soi
d = (n >= m) ? 1 : 2;
int n1 = n + 1, m1 = m + 1;
if (n1 < m1) {
int t = n1; n1 = m1; m1 = t;
}// n1 >= m1
while (m1 < n1) m1 <<= 1;
if (m1 == n1) // thua {
s = 1; // boc 1 vien tai dong d
return;
}
// Cac tinh huong thang
m1 >>= 1; s = n1 - m1;
}
Bi 3.8. Chia Hnh ch nht

Olimpic Quc t
Cho mt li ch nht kch thc NM n v nguyn. Hai bn ln lt thc hin thao tc sau y:
Ct hnh theo mt ng k trong li i qua mt im nguyn trn mt cnh v khng trng vi nh
thu c 2 hnh ch nht sau vt i hnh c din tch nh hn, trao hnh c din tch ln hn cho ngi
kia. Nu hai hnh c din tch bng nhau th vt i mt hnh ty . Bn no n lt mnh khng th thc
hin c thao tc trn th thua. Hy cho bit bn i trc thng hay thua. Gi thit rng hai bn u chi
rt gii.




4.B 5.A 6.
B 3.A

1.A 2.B
Vi hnh ch nht 5 5 u th A s thua sau 6 nc i.
Sau mi ln ct, mnh trng c din tch ln hn
s c giao cho u th tip theo,
mnh xm s c b i.

103
Gi . Bi ny hon ton tng ng nh Bi Bc si F.
Bi 3.9. Bc si G
(Dng tng qut).
Cho N ng si vi s vin si ln lt l S
i
, i = 1,2,,N. Hai ngi chi A v B, A lun i trc. Lt
chi: Chn ng ty , bc ti thiu 1 vin v ti a na s vin ca ng. u th no n lt mnh m
khng i ni th thua. Hy cho bit A thng hay thua. Gi thit rng hai u th u chi rt gii.
Bi 3.10. Chia Hnh hp
(Cho trng hp 3 ng si)
Cho mt li hnh hp ch nht kch thc NMH n v nguyn. Hai bn ln lt thc hin thao
tc sau y: Ct hnh theo mt thit din i qua mt im nguyn trn mt cnh, khng trng vi nh v
vung gc vi cnh thu c 2 hnh hp ch nht sau vt i hnh c th tch nh hn, trao hnh c
th tch ln hn cho ngi kia. Nu hai hnh c cng th tch th vt i mt hnh ty . Bn no n lt
mnh khng th thc hin c thao tc trn th thua. Hy cho bit bn i trc thng hay thua. Gi thit
rng hai bn u chi rt gii.
gii bi 3 ng si chng ta cn mt cht tr gip ca ton hc. Bn xem ba mnh di y
v gii th mt s th d nh, sau th bt tay chng minh cc mnh . Bn cng c th xem li cc
chng minh trnh by trong cc bi gii ni trn.
C s ton hc
nh ngha 1. Cc s t nhin dng 2
k
-1, k = 0, 1, 2, c gi l s Mersenne.
Th d, cc s 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 l nhng s Mersenne ng vi cc gi tr k = 0, 1,
2, 3, 4, 5, 6, 7, 8, 9 v 10.
Cc s nm gia cc s trn th d, 2, 4, 5, 6, 8, 9, 10, 11, khng phi l s Mersenne.
Mnh 1. Cho s t nhin n. Nu n khng phi l s Mersenne th ta lun lun tm c s t nhin S, 1
s S s n/2 n-S l mt s Mersenne.
Th d,
1. n = 2, S = ?
2. n = 10, S = ?
3. n = 1534, S = ?
Gi . Xc nh k 2
k
< n+1 < 2
k+1
. Sau tnh S = n+1-2
k
.
p n: 1. S = 1; 2. S = 3; 3. S = 511.
Cho 2 s t nhin n v m. Xt h thc
n + 1 = 2
k
(m + 1), k = 0, 1, 2, (*)
Mnh 2
a) Hai s Mersenne bt k u tha h thc (*).
b) C nhng cp s t nhin tha h thc (*) nhng khng phi l s Mersenne.
c) Nu cp s t nhin n v m tha h thc (*) v mt trong hai s l s Mersenne th s kia cng
phi l s Mersenne.
Gi
a) n= 2
a
-1, m = 2
b
-1,a > b n+1 = (m+1).2
a-b
.
b) Th d, 5 v 11: (11+1) = (5+1).2
1
, Vi mi a, b nguyn: 5 = 2
a
-1, 11 = 2
b
-1.
c) n+1 = (m+1).2
k
, n = 2
a
-1 2
a
= (m+1).2
k
hay m = 2
a-k
1.
Mnh 3. Cho 2 s t nhin n v m, n > m. Nu n v m khng tha h thc (*) th ta lun lun tm c
s S, 1 s S s n/2 nS v m tha h thc (*).
Th d,
1. n = 12, m = 3 , S = ?

104
2. n = 50, m = 5, S = ?
3. n = 54, m = 6, S = ?
p n: 1. S = 5; 2. S = 3; 3. S = 27.
Gi . Xc nh k max 2
k
(m+1)< n+1. Sau tnh S = n+12
k
(m+1).
Tip theo s l bi ton bc nhiu ng si vi lut bc s qun khng hn ch trong mt ng duy
nht chn.
Bi 3.11. Tr chi NIM
Tr chi NIM c xut x t Trung Hoa, dnh cho hai u th A v B vi cc nc i ln lt an nhau
trn mt u trng vi N ng si. Ngi no n lt i th c chn ty mt ng si v bc ti
thiu l 1 vin, ti a l c ng chn. Ai n lt mnh khng th thc hin c nc i s thua. Ta
gi thit l A lun i trc v hai u th u chi rt gii. Cho bit A thng hay thua?
Thut ton
Gi s vin si trong cc ng l S
1
, S
2
,, S
N
.
K hiu l tng loi tr (xor). t x = S
1
S
2
S
N
. Ta chng minh rng bt bin thua ca
tr chi NIM l x = 0, tc l nu x = 0 th n lt ai i ngi s thua.
Trc ht nhc li mt s tnh cht ca php ton theo bit.
1) a b = 1 khi v ch khi a b.
2) a 0 = a
3) a 1 = not a
4) Tnh giao hon: a b = b a
5) Tnh kt hp: (a b) c = a (b c)
6) Tnh ly linh: a a = 0
7) a b a = b
8) Tnh cht 7 c th m rng nh sau: Trong mt biu thc ch cha php xor ta c th xa i chn
ln cc phn t ging nhau, kt qu s khng thay i.
d nh ta gi php ton ny l so khc so xem hai i tng c khc nhau hay khng. Nu
khc nhau l ng (1) ngc li l sai (0).
Bt bin x = 0 c ngha nh sau: Nu vit cc gi tr S
i
, i = 1..N di dng nh phn vo mt bng
th s lng s 1 trong mi ct u l s chn.
Bng bn cho ta S
1
S
2
S
3
S
4
S
5
= 1314672 = 0.
Nu x l tng xor ca cc S
i
, i = 1..N, vi mi i = 1..N ta k hiu
K(i) l tng xor khuyt i ca cc S
i
vi cch tnh nh sau: K(i) = S
1
S
2

S
i-1
S
i+1
S
N
. Nh vy K(i) l tng xor ca cc S
j
sau khi
loi tr phn t S
i
v x chnh l tng xor ca cc S
i
, i = 1..N. Do S
i

S
i
= 0 v 0 y = y vi mi y nn K(i) = x S
i
. cho tin, ta cng
k hiu K(0) chnh l tng xor ca cc S
i
, i = 1..N. Vi th d cho
ta tnh c cc tng khuyt nh sau:
K(0) = S
1
S
2
S
3
S
4
S
5
= 1314672 = 0.
K(1) = S
2
S
3
S
4
S
5
= 14672 = 13,
K(2) = S
1
S
3
S
4
S
5
= 13672 = 14,
K(3) = S
1
S
2
S
4
S
5
= 131472 = 6,
K(4) = S
1
S
2
S
3
S
5
= 131462 = 7,
K(5) = S
1
S
2
S
3
S
4
= 131467 = 2.
Ta pht hin c qui lut l th sau y:
Dng nh phn
S1 = 13 1 1 0 1
S2 = 14 1 1 1 0
S3 = 6 0 1 1 0
S4 = 7 0 1 1 1
S5 = 2 0 0 1 0
x = 0
0 0 0 0

105
Mnh 1. Cho x l tng xor ca N s t nhin, S
i
, x = S
1
S
2
...S
N
. Khi K(i) = x S
i
, i =
1,2,...,N. Tc l mun b mt s hng trong tng ta ch vic thm tng vi chnh s hng . Ni
ring, khi x = 0 ta c K(i) = S
i
, i = 1,2,...,N.
Chng minh
Gi x l tng xor ca cc s cho, x = S
1
S
2
...S
N
. Vn dng nh giao hon v tnh ly ng
ta c th vit x S
i
= (S
1
S
2
...S
i-1
S
i+1
S
N
)(S
i
S
i
) = K(i) 0 = K(i), i = 1,2,...,N, pcm.
Ta chng minh tip cc mnh sau:
Mnh 2. Nu x 0 th c cch i hp l bin i x = 0.
Chng minh
Do x = 0 nn ta xt ch s 1 tri nht trong dng biu din nh phn ca x = (x
m
, x
m-1
,,x
0
), x
j
= 1, x
i

= 0, i > j. Do x l tng xor ca cc S
i
, i = 1..N, nn tn ti mt S
i
= (a
m
, a
m-1
,,a
0
) ch s a
j
= 1. Ta chn
ng S
i
ny (dng c du *). Khi , ta tnh c K(i) = x S
i
= (x
m
a
m
, x
m-1
a
m-1
,,x
0
a
0
) = (b
m
, b
m-
1
,,b
0
) vi b
i
= x
i
a
i
, 0 s i s m. Ta c nhn xt sau y:
* Ti cc ct i > j: b
i
= a
i
, v b
i
= x
i
a
i
= 0 a
i
= a
i
,
* Ti ct j ta c: b
j
= 0, v b
j
= x
j
a
j
= 1 1 = 0.
Do a
j
= 1, b
j
= 0 v mi v tr i > j u c b
i
= a
i
nn S
i
> K(i). Nu ta thay dng S
i
bng dng K(i)
th tng xor y khi s l
y = (x S
i
) K(i) = K(i) K(i) = 0.
Vy, nu ta bc ti ng i s vin si v = S
i
K(i) th s si cn li
trong ng ny s l K(i) v khi tng xor s bng 0, pcm.
Mnh 3. Nu x = 0 v cn ng si khc 0 th mi cch i hp l
u dn n x 0.
Chng minh
Cch i hp l l cch i lm gim thc s s si ca mt ng
S
i
duy nht no , 1 s i s N. Gi s ng c chn l S
i
= (a
m
, a
m-
1
,,a
0
). Do S
i
b sa nn chc chn c mt bit no b o (t 0
thnh 1 hoc t 1 thnh 0). Ta gi bt b sa l a
j
. Khi tng s bt
1 trn ct j s b tng hoc gim 1 n v v do s khng cn l s
chn. T suy ra rng bit j trong x s l 1, tc l x 0 pcm.
Phn lp lun ch yu trong mnh 2 nhm mc ch ch ra s tn ti ca mt tp S
i
tha tnh cht
S
i
> xS
i
. Nu tm c tp S
i
nh vy ta s bc S
i
(xS
i
) vin ti ng si i.
Gi thit rng mng S[1..N] kiu nguyn cha s lng si ca mi ng khi to nh mt i tng
dng chung, ta vit hm Ket v th tc CachDi nh sau.
Hm Ket s cho ra gi tr l tng xor x ca cc ng si. Nh vy, khi x = 0 th ngi no i s thua,
ngc li, khi x 0 th ngi no i s thng.
function Ket(N: integer): integer;
var x, i: integer;
begin
x := 0;
for i := 1 to N do x := x xor S[i];
Ket := x;
end;
Th tc CachDi hot ng nh sau:
Gi hm x = Ket. Nu x = 0 tc l s thua th chn mt ng cn si, th d ng cn nhiu si nht,
bc tm 1 vin nhm ko di cuc chi. Nu x = 0 v cc ng u ht si th ng nhin l phi chu
thua. Trng hp x = 0 th ta tm cch i chc thng nh sau:
Bc 1. Tm ng si i tha iu kin x S
i
< S
i
.
Bc 2. Bc ti ng i S
i
(xS
i
) vin.
Dng nh phn
x3 x2 x1 x0
S1 = 12 1 1 0 0
S2 = 14 1 1 1 0
* S3 = 6 0 1 1 0
S4 = 3 0 0 1 1
S5 = 2 0 0 1 0
x = 5
0 1 0 1

106
procedure CachDi(N: integer; var D,V: integer);
var x,i: integer;
begin
x := Ket(N);
if x = 0 then { Thua }
begin
D := 1;
for i := 2 to N do
if (S[i] > S[D]) then D := i;
if (S[D] = 0) {Het soi: Dau hang}
then D := 0
else S := 1;
exit;
end;
{ Chac thang }
for D:=1 to N do
if (s[D] > (x xor S[D])) then
begin
V := S[D]-(x xor S[D]); {boc V vien tai dong D }
exit;
end;
end;
Trong cc hm C# di y mng s c khai bo n phn t, cc phn t c m s t 0 n n1, trong
khi cc ng si c m s t 1 n n do chng ta phi lu chuyn i ch s cho thch hp
// C#
static int Ket() {
int x = 0;
for (int i = 0; i < s.Length; ++i) x ^= s[i];
return x;
}
static int CachDi(ref int d, ref int v) {
int x = Ket();
if (x == 0) { // Thua
d = 0;
for (int i = 1; i < s.Length; ++i)
if (s[i] > s[d]) d = i;
// s[d] = Max(s[i] | i = 0..n-1)
if (s[d] > 0){ v = 1; ++d; }
return x;
}
// Thang
for (d = 0; d < s.Length; ++d)
if ((x ^ s[d]) < s[d]){
v = s[d] - (x ^ s[d]);
++d;
return x;
}
return x;
}
Bi 3.12. C bng
Bn c l mt tm bng ch nht N dng m s t trn xung ln lt l 1, 2,...,N v M ct m s t
tri sang ln lt l 1,2,...,M; 2 s N s 500, 2 s M s 50. Mt qun c @ c t ti dng x, ct y. Hai u
th A v B lun phin mi ngi i mt nc nh sau: buc phi chuyn qun c @ t ct hin ng l y

107
sang ct k ty chn nhng phi khc ct y. Vic chuyn ny phi c thc hin nghim ngt nh sau:
trc ht y ngc qun c @ ln k dng. Nu qun c vn cn trong bng th r phi hoc tri t
qun c vo ct k, ngc li nu qun c ri ra ngoi bng th coi nh thua.
Nh vy, nu qun c ang t ti v tr (x,y) mun chuyn qun c sang ct k = y th trc ht phi
y qun c n dng x-k. Nu x-k > 1 th c php t qun c vo v tr mi l (x-k,k).
Gi thit A lun lun l u th i nc u tin v hai u th u chi rt gii. Bit cc gi tr N,
M, x v y. Hy cho bit A thng (ghi 1) hay thua (ghi 0)?
Vi N = 8, M = 4, qun c @ t ti v tr xut pht (7,2) v A i trc ta
thy A s thng sau 3 nc i an xen tnh cho c hai u th nh sau:
1. A chuyn @ t v tr @(7,2) sang v tr A
1
(4,3)
2. B chuyn @ t v tr A
1
(4,3) sang v tr B
2
(3,1)
3. A chuyn @ t v tr B
2
(3,1) sang v tr A
3
(1,2)
B chu thua v ht cch i!
Thut ton
Ta th vn dng k thut Nhn - Qu in tr 1/0 vo mi (i, j)
ca bng a vi ngha nh sau: nu gp th c c qun c @ t ti v tr (i, j) th
ai i trc s thng (1) hay thua (0). Ta s duyt theo tng dng t 1 n N, trn
mi dng ta duyt t ct 1 n ct M.
Ta c nhn xt quan trng sau y. Nu (i, j) = 0 tc l gp th thua th
cc i n c ny s l nhng th thng. chnh l cc (i+j, k) vi 1 s k
s M v k = j.
T nhn xt ny ta vit ngay c hm Ket - kim tra
xem ngi i trc vi qun c @ ti (x,y) trn bn c NM
s thng (1) hay thua (0).
Trc ht ta lp y tr 0 cho bng - mng hai chiu
a[1..N, 1..M] kiu byte, sau ln lt duyt cc phn t ca
bng v in tr 1 theo nhn xt trn.
function Ket(x,y: integer): integer;
var i,j,k: integer;
begin
fillchar(a,sizeof(a),0);
for i := 1 to x-1 do
for j := 1 to Min(x-i,M) do
if (a[i,j] = 0) then
{ in 0 cho cc (i+j, k); k=1..M, k = j }
for k := 1 to M do
if (k <> j) then a[i+j,k] := 1;
Ket := a[x,y];
end;
Thut ton trn i hi phc tp c N.M
2
.
O O O O O O O O
0 0 0 0 0 0 0 0
C 0 0 0 0 0 1 1 1
C 0 0 0 0 1 1 1 1
0 0 0 0 1 1 0 1
C 0 0 0 0 1 1 1 0
C 0 0 0 0 0 0 0 0
s O O O O
A
3

C
C
B
2

A
1

C
C
C @

Nhn xt
Nu [i, j] = 0 th mi trn dng i+j,
tr (i+j, j) u nhn tr 1.
[i, j] = 0 [i+j, k] = 1, k = 1..M, k = j.

108
C 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
Lp y 0 (bng tri) ri in tr (bng phi)
cho c bng N = 8, M = 4.
Kt qu vi x = 7, y = 2: a[7,2] = 1 (A thng).
tham gia cuc chi vi cc gi tr N, M v (x,y) cho trc d nhin bn cn tnh trc bng a
theo th tc Ket ni trn. Sau , mi ln cn i bn chn nc i theo hm CachDi nh m t di y.
Hm nhn vo cc gi tr N, M l kch thc dng v ct ca bng; dng sx, ct sy l v tr ang xt ca
qun c @ v cho ra mt trong ba gi tr loi tr nhau nh sau:
CachDi = 1 nu tm c mt v tr chc thng (nx,ny) t qun c;
CachDi = 0 nu khng th tm c v tr chc thng no nhng cn nc i do buc phi i
n v tr (nx,ny);
CachDi = -1 nu ht cch i, tc l chp nhn thua kt thc vn c.
Ta thy sau khi gi th tc Ket th dng u tin ca bng a cha tan 0 v phn t a[2,1] cng
nhn tr 0. l nhng th buc phi u hng v ht cch i. Vy tnh hung u hng (hay ht cch i)
s l
sx = 1, hoc
sx = 2 v sy = 1.
Ngoi ra, do th tc Ket c gi, tc l bng a c in th hin mi cch i ca cuc chi
nn a[sx,sy] cho ta ngay gi tr chc thng hoc chc thua ca tnh hung xut pht t (sx,sy).
Nu a[sx,sy] = 0 ta nh chn nc i c th thua chm theo Heuristic sau y: Tm cch y qun
c @ t v tr (sx,sy) ln cng t cng tt.
Nu a[sx,sy] = 1 ta chn nc i c th thng nhanh theo Heuristic sau y: Tm cch y qun c
@ t v tr (sx,sy) ln cao nht c th c, tc l ln v tr (nx, ny) tha ng thi cc iu kin
a[nx, ny] = 0,
nx cng nh cng tt.
Sau ny ta s thy cc Heuristics trn ch l mt cch i tt ch cha phi l cch i ti u.
function CachDi(M, sx, sy: integer; var nx,ny: integer): integer;
begin
if (sx = 1) or ((sx = 2) and sy = 1)) then
begin { Het cach di: Dau hang }
CachDi := -1;
exit;
end;
CachDi := a[sx,sy];
if CachDi = 0 then { Con nuoc di nhung se thua }
for ny := 1 to Min(sx-1,M) do
if (ny <> sy) then
begin
nx := sx ny;
exit;
end;
{ Chac thang }
for ny := Min(sx-1,M) downto 1 do
if (ny <> sy) then
if (a[sx-ny,ny] = 0) then
begin { chac thang }
nx := sx ny; exit;
end;
end;

109
end;
Hm Min(a,b) cho ra gi tr min gia hai s a v b cn dc m t trc nh sau:
function Min(a,b: integer): integer;
begin
if (a < b) then Min := a else Min := b;
end;
Chng trnh C# di y m t mt vn C Bng 50 7 gia hai u th A (i trc) v B. Qun
c xut pht ti v tr (49,5). Vn ny A s thng.
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1 {
class Program {
static int maxn = 501, maxm = 51;
static int[,] a = new int [maxn,maxm];
static void Main(string[] args){
Game(50, 7, 49, 5);
Console.WriteLine("\n \n Fini");
Console.ReadLine();
}
static void Game(int n, int m, int x, int y) {
Console.WriteLine("\n The co " + n +
" X "+m+" @ = ("+x+","+y+")");
Ket(m, x, y);
Show(a, x, m);
while (true) {
Console.Write("\n A: ( " + x + " , " + y + " ) ");
if (CachDi(m, x, y, ref x, ref y) == -1) {
Console.Write("Dau hang !!!");
Console.ReadLine();
return;
}
else Console.Write(" ==> ( " + x + " , " + y + " ) ");
if (Console.Read() == '.') return;
Console.Write("\n B: ( " + x + " , " + y + " ) ");
if (CachDi(m, x, y, ref x, ref y) == -1) {
Console.Write("Dau hang !!!");
Console.ReadLine();
return;
}
else Console.Write(" ==> ( " + x + " , " + y + " ) ");
if (Console.Read() == '.') return;
} // while
}
static int CachDi(int m, int sx, int sy, ref int nx, ref int ny)
{
if (sx == 1 || (sx == 2 && sy == 1)) return -1;
if (a[sx, sy] == 0) { // Di duoc, nhung thua
for (ny = 1; ny <= Min(sx-1,m);++ny)
if (ny != sy) { nx = sx - ny; return 0; }
}
for (ny = Min(sx-1,m); ny > 0; --ny)
if (ny != sy)
if (a[sx - ny, ny] == 0) // Chac thang
{ nx = sx - ny; return 1; }

110
return 0;
}
static int Min(int a, int b) { return (a < b) ? a : b; }
static int Ket(int m, int x, int y) {
Array.Clear(a,0,a.Length);
for (int i = 1; i < x; ++i) { // voi moi dong i
int minj = Min(x - i, m);
for (int j = 1; j <= minj; ++j) // xet cot j
if (a[i, j] == 0)
for (int k = 1; k <= m; ++k)
if (k != j) a[i + j, k] = 1;
}
return a[x, y];
}
static void Show(int[,] s, int n, int m) {
Console.WriteLine();
for (int i = 1; i <= n; ++i) {
Console.Write("\n"+i+". ");
for (int j = 1; j <= m; ++j)
Console.Write(a[i, j] + " ");
}
}
}// Program
}
Nu N c kch thc ln, th d, c triu dng, cn s ct M vn nh, th d M s 50 v ra ch
yu cu cho bit ngi i trc thng hay thua ch khng cn l gii tng nc i th ta vn c th s dng
mt mng nh c 5151 phn t gii bi ton trn. Ta khai bo kiu mng nh sau:
const mn = 51;
type
MB1 = array[0..mn] of byte;
MB2 = array[0..mn] of MB1;
var a: MB2;
N: longint;
M: integer;
....
Ta s dng mng index di y chuyn i cc s hiu dng tuyt i thnh s hiu ring trong
mng nh a. bn ch cn lu nguyn tc sau y khi x l cc php thu gn khng gian: Khng ghi vo
vng cn phi c d liu. Thc cht y l mt hm bm cc gi tr i trong khong 1..N vo min 0..M
bng php chia d: i (i-1) mod (M+1) nh m t trog hm index.
function index(i,M: integer): integer;
begin
index := i mod (M+1);
end;
function Ket(M: integer;
x: longint; y: integer): integer;
var i: longint; j,k: integer;
begin
fillchar(a,sizeof(a),0);
for i:= 1 to x-1 do
begin
k := index(i+M,M);
fillchar(a[k],sizeof(a[k]),0);
for j:=1 to Min(x - i, M)do
if (a[index(i,M),j] = 0) then
for k := 1 to M do

111
if (k <> j) then
a[index(i+j,M),k] := 1;
end;
Ket := a[index(x,M),y];
end;
//C#
static int Index(int i, int m) { return i % (m + 1); }
static int Ket(int m, int x, int y){
int id, Minj, i, j, k, v ;
Array.Clear(a, 0, b.Length);
for (i = 1; i < x; ++i) {
id = Index(i + m, m);
for (v = 1; v <= m; ++v) a[id, v] = 0;
minj = Min(x - i, m);
for (j = 1; j <= minj; ++j) // xet cot j
if (a[Index(i, m), j] == 0)
for (k = 1; k <= m; ++k)
if (k != j) a[Index(i + j, m), k] = 1;
}
return a[Index(x,m), y];
}
n y ta th m rng iu kin ca bi ton nh sau: Hy cho bit, vi cc gi tr cho trc l
kch thc bng N M, v tr xut pht ca qun c @ (x,y) v u th A i trc th A thng hoc thua sau
bao nhiu nc i ?
Nguyn tc ca cc tr chi i khng

Nu bit l thng th tm cch thng nhanh nht,
Nu bit l s thua th c ko di cuc chi
c th thua chm nht.
Ta vn s dng bng A in tr vi cc qui c mi sau y:
Nu t (i, j) ngi i trc c th thng sau b nc i th ta t a[i,j] = +b; ngc li nu t ny
ch c th dn n th thua sau ti a b nc i th ta t a[i,j] = b. Mt nc i l mt ln di chuyn qun
c ca mt trong 2 ngi chi. Ta cng qui c a[i,j] = 0 c ngha l u th xut pht t (i,j) s ht cch
i do chp nhn thua ngay. K hiu (i,j) (u,v) nu c nc i hp l t (i,j) sang (u,v). T nguyn
tc ca cc tr chi i khng ta suy ra
(1) Nu t (i,j) c nhng nc i hp l dn n th (lm cho i phng) thua th ta chn
cch thng nhanh nht bng cch t
a[i,j] = min { a[u,v] | (i,j) (u,v), a[u,v] s 0 } + 1
(2) Nu t (i,j) mi nc i hp l u dn n th (to cho i phng thng) th ta phi
chn cch thua chm nht bng cch t
a[i,j] = (max { a[u,v] | (i,j) (u,v), a[u,v] > 0 } + 1)





1 2 3 4
1 0 0 0 0

112
Sau khi lp y 0 cho bng a ta ln lt duyt cc dng i t 1 n x. Vi mi
dng ta duyt cc ct j t 1 n M. Nu gp tr a[i,j] = 0 ta hiu l v tr ny s dn
n thua. Ta cn tnh s bc thua chm nht ri gn cho a[i,j]. Tip n, do v tr
(i,j) l thua nn ta phi cp nht li cc gi tr a[u,v] ng vi cc v tr (u,v) (i,j).
Bn th in tr cho bng a vi N = 12, M = 4. Trong th d ny, a[8,2] = - 4
c ngha l nu qun c @ t v tr (8,2) th ngi i trc s thua sau 4 nc
i. Tht vy, gi A l ngi i trc, ta thy nu A di chuyn @ n (7,1) th B s
i tip thng sau 3 nc i; A khng th n dng 6 (?). Nu A n (5,3) th B
s i tip thng sau 1 nc. Nu A n (4,4) thi B s i tip 1 nc na n
(1,3) l thng.
Ti sao trong hm Ket ta phi tnh th thua trc khi tnh th thng. V khi
gp a[i,j] = 0 th ta cn cp nht gi tr ny bit c l s thua sau bao nhiu
nc i. Sau , do c ch lp lun li, ch khi no ta bit s nc thua ti a[i,j] th
mi tnh tip c cc th thng dn n h thua ny.
function Ket(M,x,y: integer): integer;
var i, j: integer;
begin
fillchar(a,sizeof(a), 0);
for i := 1 to x do
for j := 1 to M do
if (a[i,j] = 0) then
begin
TinhNuocThua(M,i,j);
TinhNuocThang(M,x,i,j);
end;
Ket := a[x,y];
end;
Procedure TinhNuocThua(M,i,j: integer);
var k, vmax: integer;
begin
vmax := -1;
for k := 1 to Min(i-1,M) do
if (k <> j) then
vmax := Max(vmax, a[i-k,k]);
a[i,j] := -(vmax + 1);
end;
Procedure TinhNuocThang(M,x,i,j: integer);
var k, d, v: integer;
begin { Xet dong i+j }
d := i+j;
if (d <= x) then { quan co con trong vung can xu ly }
begin
v := -a[i,j] + 1;
for k := 1 to M do
if (k <> j) then
if (a[d,k] > 0) then a[d,k] := Min(a[d,k], v)
else a[d,k] := v;
end;
end;
// C#
static int Ket(int n, int m, int x, int y) {
Array.Clear(a, 0, a.Length);
for (int i = 1; i <= x; ++i) { // voi moi dong i
for (int j = 1; j <= m; ++j) // xet cot j
2 0 1 1 1
3 1 1 1 1
4 1 1 -2 1
5 1 1 1 -2
6 -2 -2 -2 -2
7 3 3 3 3
8 3 -4 3 3
9 3 3 3 3
10 3 3 3 5
11 -4 -4 -4 -4
12 -4 5 5 5
Tab Game vi
N = 12, M = 4.

113
if (a[i, j] == 0) {
TinhNuocThua(m, i, j);
TinhNuocThang(m, x, i, j);
}
}
return a[x,y];
}
static void TinhNuocThua(int m, int i, int j) {
int vmax = -1, km = Min(i-1,m);
for (int k = 1; k <= km; ++k)
if (j != k) vmax = Max(vmax, a[i - k, k]);
a[i,j] = -(vmax + 1);
}
static void TinhNuocThang(int m, int x, int i, int j){
int d = i + j;
if (d > x) return;
int vmin = -a[i,j]+1;
for (int k = 1; k <= m; ++k)
if (k != j)
a[d,k] = (a[d, k] > 0) ? Min(a[d, k], vmin) : vmin;
}
Vi N c triu v M nh bn cng c th vn dng cc k thut tng t nh trnh by c
th tnh s nc thng/thua, tuy nhin trong trng hp ny bn phi khai bo mng a rng gp i, tc l a
phi cha 2M+2 dng gm M dng trc dng ang xt v M dng sau dng ang xt. cc dng trc v
sau ny dng cp nht s nc i thng/thua.
n y ta c th s dng thut ton C bng gii bi C y
sau y.
Bi 3.13. C y
Bn c l mt gii bng chia m s t 1 n N. Hai u th A v
B an xen nhau, mi ngi i mt nc, A lun i trc. Mt qun c @
t cnh x. Ti nc i th i phi y qun c ln (v pha ch s nh) d
i

, 1 s d
i
s M v khng c lp li cch va i ca u th trc, tc l
d
i
= d
i-1
. u th no n lt mnh khng i ni th thua. Gi thit l hai
u th u chi rt gii. Bit N, M, x v A l u th i trc. Hy cho
bit
a) A thng (ghi 1) hay thua (ghi 0).
b) A thng hay thua sau bao nhiu ni i?
Gi s hai u th i v nc i vi mc y ln lt l d
1
, d
2
,..., d
v

th gi thit ca bi cho bit hai mc y k nhau l d
i-1
v d
i
phi khc
nhau. Gi s bn c c N = 12 , qun c t cnh x = 7, mi nc i
phi di chuyn qun c ln 1, 2.., hoc M = 4 v khng c lp li nc
va i ca ngi trc. Nu A i trc th s c th thng sau ti a 4 nc
i. Chng hn, A i ln 1 bc d
1
= 1 n 6. B c th chn mt trong 3
cch i ng vi d
2 =
2, 3, hoc

4. n 4, 3 hoc 2. Nu B chn d
2
=
2 n 4 th A di chuyn ln theo d
3
= 3 n 1 khin cho B thua.
Nu B chn d
2
= 3 n 3 th A di chuyn ln theo d
3
= 2 n 1
khin cho B thua. Cui cng, nu B chn d = 4 n 2 th A di chuyn ln theo d
3
= 1 n 1 khin
cho B thua. cc gi tr d
i
theo tng phng n khi l nh sau:
Phng n 1: (1, 2, 3).
Phng n 2: (1, 3, 2).
Phng n 3: (1, 4, 1).
Thut ton
0 1 2 3 4
1 0 0 0 0
2 0 1 1 1
3 1 1 1 1
4 1 1 -2 1
5 1 1 1 -2
6 -2 -2 -2 -2
7 @ 3 3 3 3
8 3 -4 3 3
9 3 3 3 3
10 3 3 3 5
11 -4 -4 -4 -4
12 -4 5 5 5
C y N = 12, M = 4, x = 7
v Tab Game tng ng.

114
Chng ta hy thit lp s tng ng gia c y v c bng v ch ra rng A thng c y khi v ch
khi A thng c bng tng ng. C y N , gii hn bc i M v xut pht x tng ng vi c bng N
di, M ngang v v tr xut pht (x,y) trong y = d
1
l nc i hp l u tin n 1 thua, x := x-d
1
.
C mt cch t duy c th d dng tnh c (x,y) nh sau. Ta thm cho c bng mt gi mang
m s 0 v qui nh rng qun c bng xut pht ti (x,0) - dng v, ct 0. Sau , trong cuc chi vi c
bng ny khng ai c php di chuyn n ct 0. Nu A i u tin th chc chn s di chuyn t (x,0)
n mt m B chc thua. Trong th d ny, nc i u tin ca A s l (7,0) (6,1), tc l chuyn qun
c t ct 0 sang ct 1.
Bi c y mi xem tng nh n gin nhng gii c ta li phi xt bi kh hn nhng c li
gai trong sng, d hiu
Bi 3.14. Bc si H
Dng pht biu khc ca bi C y
Cho ng si N vin, hai u th A v B ln lt i, A i nc u tin. Mi nc i u th buc
phi bc ti thiu 1 vin, ti a M vin trong ng v khng c lp li nc va i ca ngi trc. Th
d, nu u th A va bc v vin si th n lt mnh, u th B khng c bc v vin na. u th no
n lt mnh khng i ni th thua. C hai u th u chi rt gii. Cho bit a) A thng hay thua. b) A
thng hay thua sau bao nhiu ni i?



115
Chng 4
Cc thut t on sp t

4.1 C tam ti
Olimpic quc t
Mt s quc gia nh Ba Lan, B, Php c
quc k to t ba gii mu thng c gi l c
tam ti. Ba bn tr A, B v C chi tr ghp hnh
to thnh mt l c tam ti vi ba gii mu dc ln
lt tnh t tri qua phi l xanh (X), trng (T) v
(D). Mt bn ghp c c kch thc 2N 3N
vung n v c k sn thnh li vung vi
m s cc hng tnh t trn xung di l 1, 2,,
2N v m s cc ct tnh t tri qua phi l 1, 2,,
3N. u tin bn A chn mt trn ct 1 c ta
l (Ax, Ay = 1), bn B chn mt trn dng cui
cng c ta l (Bx=2N, By), bn C chn mt
trn ct cui cng c ta l (Cx, Cy = 3N). Sau
ln lt theo th t quay vng A, B, C ba bn
chn cc mnh ghp n v 1 1 vi mu ph hp
t vo cc trong bn c. Ln u tin mi
bn t mt mnh ghp vo chn. Nhng ln tip theo, n lt mnh, mi bn t mt s mnh ghp
k vi mnh ghp do chnh bn y t ti ln trc. D nhin, mi trn bn ch c t ng 1 mnh
ghp. Bn no khng th ghp c th bn ngng chi, nhng ngi cn li s tip tc chi n khi
hon thnh l c. Bit cc gi tr N, Ax, By v Cx. Hy cho bit mi bn ghp c bao nhiu mnh mi
mu.
Vi th d nh trong hnh, N = 2, Ax = 2, By = 2, Cx = 3 ta tnh c kt qu nh trong bng.
ngha ca cc trn bn ghp c cho bit bn no trong ln i th my ca mnh, ghp mnh mu g. Th
d, A5:T cho bit bn A, trong ln i th 5 ghp mnh mu trng. xut pht ca mi bn k hiu l 0.

O O O O O O

C
A1:X A2:X A3:T A4:T C3:D C2:D Xanh Trng
C
A0:X A1:X A2:T A3:T C2:D C1:D A 5 4 0

A
C
B
C tam ti 4 6
N = 2

116
C
A1:X B1:X B2:T C2:T C1:D C0:D B 3 3 0
C
B1:X B0:X B1:T B2:T C2:D C1:D C 0 1 8
C tam ti, N = 2, A(2,1), B(4,2), C(3,6)
X: Xanh, T: Trng, D: .
Kt qu

Thut ton
Bi ny kh d gii. Nu bn kho t chc d liu th chng trnh s rt gn. Trc ht ta cn xc
nh rng mi (i,j) trn bn c s do bn no ghp: A, B hay C ? Ta nh ngha khong cch gia hai
(i,j) v (x,y) trn bn c l s t nht nm trn ng i t ny n kia qua cc k cnh nhau.
Khong cch ny chnh l tng chiu di hai cnh k nhau ca hnh ch nht nhn hai cho lm hai
nh i din, do c tnh theo cng thc
d = abs(i-x) + abs(j-y) +1
Gi tr d c ngha g ? Nu ta qui nh nh s cc ln i cho mi u th l 0, 1, 2, th d-1 cho
bit ln i th my ca mi bn. V trt t tnh ln i ca cc bn l A B C nn ta cn xc nh gi tr
min trong ba khng cch d
A
, d
B
v d
C
. Tuy nhin chng ta s khn ngoan mt cht, c th l ta s tnh d
theo cng thc ht 1
d = abs(i-x) + abs(j-y)
v vit hm min3 nhn vo l ba gi tr d
A
, d
B
v d
C
v cho ra l tn ca ngi c ghp mnh ti
ang xt.
function Min3(a,b,c: integer): char;
var k: char;
begin
k := 'A';
if a > b then begin k := 'B'; a := b end;
if a > c then k := 'C';
Min3 := k;
end;
Sau khi xc nh c ch ca mnh ghp ti (i,j) ta d dng tnh c mu ca mnh ghp ti
. V l c c ba mu v ta tm qui c cc gii mu tnh t tri qua phi l 0, 1 v 2 nn mu cn chn
t ti (i,j) khi s l (j-1) div N.
Ta khai bo mng kq dng tch ly kt qu nh sau:
kq: array['A'..'C',0..2] of integer;
Khi c[v,i] s cho bit bn v ghp bao nhiu qun mu i, v = 'A', 'B', 'C'; i = 0 (mu Xanh), 1
(mu Trng), 2 (mu ).
Cc bin chung ca chng trnh s l:
var
n: integer; { Ban co co kich thuoc 2n3n }
Ax,Ay,Bx,By,Cx,Cy: integer; { Toa do xuat phat cua A, B, C }
kq: array['A'..'C',0..2] of integer; { Chua ket qua }
Th tc XuLi s duyt ln lt mi (i , j) trn bn c, xc nh ch nhn ca ny v s mu ca
mnh cn ghp tch ly cho ch nhn .
procedure XuLi;
var i,j: integer;
begin
fillchar(kq,sizeof(kq),0);
for I := 1 to 2*N do
for j := 1 to 3*N do
inc(c[Min3(abs(i-Ax)+abs(j-Ay),abs(i-Bx)+abs(j-By),

117
abs(i-Cx)+abs(j-Cy)),(j-1) div N]);
end;
Chng trnh C#
Chng trnh C# di y thc hin vi d liu cho trc N = 2, A(2,1), B(4,2), C(3,6).
// C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao2 {
class CoTamTai {
static int n = 2; // Ban co kich thuoc 2N3N
static int [,] kq = new int [3,3];
static int Ax = 2, Ay = 1, Bx = 2*n, By = 2,
Cx = 3, Cy = 3*n; // Toa do xuat phat

static void Main(string[] args) {
XuLi();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j)
Console.Write(KQ[i, j] + " ");
Console.WriteLine();
}
Console.ReadLine();
}
static int Min3(int a, int b, int c) {
int min = 0;
if (a > b) { min = 1; a = b; }
if (a > c) min = 2;
return min;
}
static void XuLi() {
Array.Clear(Kq,0,Kq.Length);
int n2 = 2 * n;
int n3 = 3 * n;
for (int i = 1; i <= n2; ++i)
for (int j = 1; j <= n3; ++j)
++KQ[Min3(Math.Abs(i-Ax)+Math.Abs(j-Ay),
Math.Abs(i-Bx)+Math.Abs(j-By),
Math.Abs(i-Cx)+Math.Abs(j-Cy)),(j-1)/n];
}
} // Co Tam Tai
} // SangTao2
phc tp
Ta phi duyt mi trn bn c vy phc tp tnh ton c N
2
.
Bi sau y tng t nh bi trn nhng kh hn v cc th tc m ha.
4.2 Li tam gic u
Cho tam gic u ABC, nh A, cnh di N n v. Ti cc im chia nguyn trn cc cnh ta k cc
ng thng song song chia tam gic thnh N
2
tam gic n v (TGV). M s cho cc TGV theo trt t
t trn xung v t tri qua phi l 1, 2, , N
2
. Ba bn A, B v C c cp mi bn mt TGV khc nhau
lm ni xut pht trn cc cnh AB cho bn A, BC cho bn B v AC cho bn C. Ln lt theo th t quay

118
vng A, B, C vit ch ci tn mnh vo cc TGV k cnh vi cc tam gic m mnh vit ln
trc. Bit cc gi tr N, v cc im xut pht NA, NB v NC, tnh s ch ci mi loi mi bn vit.
T chc d liu
Cc bin dng chung:
var n: longint; { Do dai canh tam giac }
f,g: text; { input, output file }
AN, BN, CN: longint; { O xuat phat }
Ad, Av, Bd, Bv, Cd, Cv: longint; { Toa do xuat phat }
Ak,Bk,Ck: longint;
A,B,C: longint; { con dem }
Kq: array [A..C] of longint;
trong n l chiu di mt cnh ca tam gic u; AN, BN v CN l s hiu ca cc xut pht
tng ng cho A, B v C.
Thut ton
Xt cc tam gic n v t nh xung n cnh y ca bn c. Ta thy, trn dng 1 c 1 TGV,
dng 2 c 3, dng 3 c 5 TGV... Tng qut, trn dng i tnh t nh xung n y s c 2*i -1 TGV.
Trn mi dng i ta gn s hiu cho cc TGV l 1, 2, ... , 2i-1. Ta nh ngha ta ca mt tam gic
n v c s hiu (tuyt i theo u bi) cell l cp s (d,v) trong d l s hiu dng cha TGV v v
l s hiu ca tam gic trn dng d. Th tc ToaDo di y tnh ta cho mt TGV theo cell - s
hiu (tuyt i) ca TGV nh cch m s ca bi. Th tc cho ra hai gi tr, dong - dng cha TGV
cell v viTri - s hiu ca TGV trn dng m ta gi l s hiu tng i. Th d, ToaDo(15,d,v)
cho ta d = 4, v = 6.



C9

1

3

A2

4

8
7

6

5

10

11

13
12

B14

15

16

Li Tam gic N = 4, NA = 2, NB = 14,
NC = 9.
Kt qu, A: 9, B: 5, C: 2.

119
procedure ToaDo(cell: longint;var dong, viTri:longint);
begin
dong := 0;
while cell > 0 do
begin
dong := dong + 1;
cell := cell - (2*dong-1);
end;
viTri := cell + (2*dong-1);
end;
Hm KhoangCach di y tnh khong cch gia hai TGV theo ta (d1,v1) v (d2,v2),
trong d1, d2 l s hiu dng, v1 v v2 l s hiu tng i ca chng (trn dng). Ging nh bi trc,
khong cch trong bi ny chnh l s TGV t nht, k cnh nhau trn ng i t TGV (d1,v1) n
TGV (d2,v2). Trc ht ta i ch hai ta , nu cn, sao cho tam gic th nht lun lun nm dng
trn so vi tam gic th hai, tc l d1 s d2. Sau ta nhn xt nh sau:
Nu mt TGV c nh quay ln trn th
* S hiu tng i ca n l s l, v
* N s l nh ca mt tam gic u cha n v c cc cnh song song vi cc cnh ca bn c.
Nu mt TGV c nh quay xung di th
* S hiu tng i ca n l s chn, v
* TGV k cnh vi n trn cng dng s c nh quay ln trn.
Ta gi cc TGV c nh quay ln trn l tam gic l phn bit vi cc TGV chn - c nh
quay xung di.
Nu TGV th nht (d1,v1) l tam gic l ta xt tam gic ln hn to bi cc TGV nhn tam gic
l ny lm nh v c cnh y trn dng d2. Ta tnh hai nh trn y ca tam gic ny trn dng d2 l C1
v C2 theo cng thc
d := 2*(d2 - d1);
c1 := v1;
c2 := v1 + d;
Tip n ta xt v tr v2 trn cnh y c th nm gia C1 v C2 hoc nm ngoi oan [C1, C2]
ng thi xt v2 l tam gic chn hay l.
function KCLe(d1,v1,d2,v2: longint):longint;
var c1,c2,d: longint;
begin
{ v1 <= v2 }
d := 2*(d2 - d1);
c1 := v1;
c2 := v1 + d;
if (c1 <= v2) and (v2 <= c2) then
begin
if odd(v2) then KCLe := d
else KCLe := d - 1;
exit;
end;
KCLe := d + Min(abs(v2-c1),abs(v2-c2));
end;
Nu TGV th nht (d1,v1) l tam gic chn th ta li li mt dng d xt TGV l c chung y
vi TGDV th nht ri tnh ton nh trn v gim kt qu 1 n v.
function KhoangCach(d1,v1,d2,v2: longint):longint;
var t: longint;
begin
if d1 > d2 then
begin

120
t := v1; v1 := v2; v2 := t;
t := d1; d1 := d2; d2 := t;
end;
{ v1 <= v2 }
if odd(v1) then KhoangCach := KCLe(d1,v1,d2,v2)
else KhoangCach := KCLe(d1-1,v1-1,d2,v2) - 1;
end;
procedure XuLi;
var d,v,j: longint;
Ad, Av, Bd, Bv, Cd, Cv: longint;
begin
fillchar(kq,sizeof(kq),0);
ToaDo(NA, Ad, Av);
ToaDo(NB, Bd, Bv);
ToaDo(NC, Cd, Cv);
for d := 1 to N do
for v := 1 to 2*d - 1 do
inc(kq[Min3(KhoangCach(Ad,Av,d,v),
KhoangCach(Bd,Bv,d,v),
KhoangCach(Cd,Cv,d,v))]);
end;
Chng trnh C#
Chng trnh C# di y gii bi ton vi d liu cho trc N = 4, A, B v C ln lt xut pht ti
cc TGV 2, 14 v 9 nh th d cho.
// C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao2 {
class TamGiacDeu {
static int n = 4, NA = 2, NB = 14, NC = 9;
static int[] Kq = new int[3];
static void Main(string[] args){
XuLi();
for (int i = 0; i < 3; ++i)
Console.Write(KQ[i] + " ");
Console.ReadLine();
}
// Tinh dong va vi tri tren dong
// theo so hieu cua TGDV
static void ToaDo(int cell, out int dong, out int viTri){
dong = 0;
while (cell > 0){
++dong; cell -= (2*dong - 1);
}
viTri = cell + (2*dong - 1);
}
static int KhoangCach(int d1, int v1, int d2, int v2){
if (d1 > d2){
int t;
t = d1; d1 = d2; d2 = t;
t = v1; v1 = v2; v2 = t;
}
return (v1%2==1)?KCLe(d1,v1,d2,v2):KCLe(d1-1,v1-1,d2,v2)-1;

121
}
static int KCLe(int d1, int v1, int d2, int v2){
int c1=v1, d=2*(d2-d1), c2=v1+d;
// Xet tam giac voi 3 dinh v1 c1 c2
if (c1 <= v2 && v2 <= c2)
return (v2 % 2 == 1) ? d : d-1;
return d + Math.Min(Math.Abs(v2-c1),Math.Abs(v2-c2));
}
static int Min3(int a, int b, int c){
int min = 0;
if (a > b) { min = 1; a = b;}
if (a > c) min = 2;
return min;
}
static void XuLi(){
int Ad, Av, Bd, Bv, Cd, Cv;
ToaDo(NA,out Ad, out Av);
ToaDo(NB,out Bd, out Bv);
ToaDo(NC,out Cd, out Cv);
Array.Clear(Kq, 0, Kq.Length);
for (int d = 1; d <= n; ++d){
int vv = 2*d-1;
for (int v = 1; v <= vv; ++v)
++KQ[Min3(KhoangCach(Ad,Av,d,v),
KhoangCach(Bd,Bv,d,v),
KhoangCach(Cd,Cv,d,v))];
}
}
} // Tam Giac Deu
} // SangTao2
phc tp
Ta phi duyt mi TGV trn bn c, vy phc tp tnh ton c N
2
.
4.3 Dng biu din ca giai tha
Cho s t nhin n s 480.000. Hy phn tch n! ra tch ca cc tha s nguyn t theo trt t tng
dn. Th d, 13! = 2
10
.3
5
.5
2
.7.11.13. Kt qu hin th di dng cc dng, mi dng mt s nguyn t tip
n l s m tng ng. Cc s trn cng dng cch nhau qua du cch. Th d trn cho ta kt qu hin th
nh sau
2 10
3 5
5 2
7 1
11 1
13 1
Thut ton
Nhn xt Cho s t nhin N v mt s nguyn t p. Khi ,
Nu vit dy tha s 1, 2, ..., N vo mt bng c p ct th ta thy c n
1
= N div p dng cha p,
2p,...,n
1
.p ( ct cui cng). Nhm cc phn t ny li ta c,
1p.2p....n
1
p = (1.2...n
1
).p
n1
. Thc hin tng t vi tch 1.2...n
1
ta thu c n
2
= n
1
div p dng cha
p, 2p,...,n
2
.p... T y ta suy ra ly tha k ca p, p
k
trong dng phn tch ca N! s l k = n
1
+n
2
+...+n
v
, trong

122
n
i
= n
i-1
div p, n
1
= N div p, n
v
= 0, i = 2..v. Hm tnh ly tha ca p trong dng phn tch ca N! bng
cc php chia lin tip khi s nh sau,
function Power(n,p: longint): byte;
var k: byte;
begin
k := 0;
while (n <> 0) do
begin
n := n div p;
k := k + n;
end;
Power := k;
end;
Ta dng hm NextPrime sinh ln lt cc s nguyn t p trong khong 2..N v tnh
Power(N,p). Nu gi tr ny ln hn 0 th ta hin th kt qu.
procedure Fac(n: longint);
const bl = #32; { Dau cach }
var p: longint; k: byte;
begin
writeln;
p := 2;
while p <= n do
begin
k := Power(n,p);
if (k > 0) then writeln(p,bl,k);
p := NextPrime(p);
end;
end;
Hai hm ph tr.
Hm IsPrime(p) kim tra p c phi l s nguyn t hay khng bng cch xt xem trong khong
t 2 n p c c no khng.
function IsPrime(p: longint): Boolean;
var i: longint;
begin
IsPrime := false;
if p < 2 then exit;
for i := 2 to round(sqrt(p)) do
if p mod i = 0 then exit;
IsPrime := True;
end;
Hm NextPrime(p) sinh s nguyn t st sau p bng cch duyt tun t cc s l sau p l p+2k
nu p l v (p-1) + 2k, nu p chn.
function NextPrime(p: longint): longint;
begin
if p < 2 then
begin
NextPrime := 2;
exit;
end;
if not odd(p) then p := p-1;
repeat
p := p+2;
until IsPrime(p);

123
NextPrime := p;
end;
Ta c th ci tin kh mnh tc tnh ton bng cc k thut sau.
Sinh sn cc s nguyn t trong khong t 1..N bng gii thut Sng mang tn nh ton hc Hi Lp
Eratosthene. T vi nghn nm trc, Eratosthenes dy nh sau:


Ba ging ca Eratosthenes


Nu tr mun lit k ton b cc s nguyn t
nm trong khong t 1 n N hy lm nh sau
1. Vit dy s t 1 n N.
2. Xa i s 1 v n khng phi l s nguyn t, cng
khng phi l hp s. N l mt s c bit.
3. Ln lt duyt t 2 n N nh sau. Nu gp s
cha b xa th chnh l mt s nguyn t. Tr hy
xa mi bi ca s ny k t bnh phng ca n tr i.
Khi kt thc, nhng s no khng b xa trn tm
bng s l cc s nguyn t. l kho cc s nguyn t
trong khong 1..N.

Thi cha c giy vit nn thy tr phi vit trn nhng tm bng bng t st vo lc t cn
do, cc s b xa c c thng. Sau khi phi kh ta thu c nhng tm bng thng l ch nh mt ci
sng go.
Vi mng a[0..MN] of byte ln, th d, MN = 60.000 ta c th ghi nhn cc s nguyn t
nm trong khong 1..MN. Ta qui c a[i] = 0 th i l s nguyn t, a[i] = 1 ng vi s i b di thng nn i
khng phi l s nguyn t.
procedure Eratosthenes(n: longint);
var i,j: longint;
begin
fillchar(a,sizeof(a),0);
for i := 2 to round(sqrt(n)) do
if a[i]=0 then
for j := i to (n div i) do a[i*j] := 1;
end;
Th tc phn tch N! ra tha s nguyn t dng ci tin s nh sau,
procedure NewFac(n: longint);
const bl = #32; { Dau cach }
var i,p: longint;
begin
Eratosthenes(n);
writeln;
for i := 2 to n do
if a[i] = 0 then
begin
p := Power(n,i);
if P > 0 then writeln(i,bl,p);
end;
Sau ng c giao ph trch th
vin Alexandria, mt trung tm lu tr
v bo tn cc tc phm vn ha v khoa
hc ni ting ng thi. Ngoi cc
cng trnh tan hc, Eratosthenes cn c
nhng ng gp rt gi tr v o lng.
ng tin hnh o kch thc Tri t.

Eratosthenes (276-194 tr.
CN) Nh ton hc li lc Hy
Lp C i. ng sinh ti
Cyrene, theo hc trng phi
Plato ti Athens. Hong
Ptolemy II mi ng n
Alexandria dy cho hong
t.

124
end;

Dng k thut nh du bit c th to kho s nguyn t c 8.MN v mt byte c 8 bit, mi bit s
qun l 1 s.
Mng a vn c khai bo nh trc: a[0..MN] of byte (quan trng l ch s phi tnh t 0
tr i) nhng lc ny mi phn t a[i] s qun l 8 s ch khng phi mt s nh trc. Tip n bn cn
vit thm ba th tc sau y:
Th tc BitOn(i) - t tr 1 cho bit th i trong dy bit a (bt bit). Cc bit trong dy a s c m
s t 0 n 8MN-1= 480.000-1. Bn thn s 480.000 l hp s nn ta c th b qua.

procedure BitOn(i: longint);
var b,p: longint;
begin
b := i shr 3; { i div 8 }
p := i and 7; { i mod 8 }
a[b] := a[b] or (1 shl p);
end;

t tr 1 cho bit i trong dy bit a
1. Xc nh xem bit i nm trong byte no
b := i div 8
2. Xc nh xem bit i l bit th my trong byte b
(tnh theo trt t 7,6,5,4,3,2,1,0)
p := i mod 8
3. Ly s nh phn 8 bit 00000001 dch tri p v
tr ri cng logic theo bit vi a[b].
a[b] := a[b] or (1 shl p);

Bn ghi nh s tng ng ca cc php ton sau y
Php
ton
Php ton tng ng
x div
2
k
x shr k
x mod
2
k
x and 2
k
-1
Tnh theo dng ny s nhanh
hn

Th tc BitOff(i) t tr 0 cho bit th i trong dy bit a (tt bit).
procedure BitOff(i: longint);
var b,p: longint;
begin
b := i shr 3; { i div 8 }
p := i and 7; { i mod 8 }
a[b]:=a[b] and (not(1 shl p));
end;


t tr 0 cho bit i trong dy bit a
1. Xc nh xem bit i nm trong byte no
b := i div 8;
2. Xc nh xem bit i l bit th my trong byte b
(tnh theo trt t 7,6,5,4,3,2,1,0)
p := i mod 8;
3. Ly s nh phn 6 bit 00000001 dch tri p v
tr, lt ri nhn logic theo bit vi a[b].
a[b]:=a[b] and (not(1 shl p));

Hm GetBit(i) cho ra tr (1/0) ca bit i trong dy bit a.
function GetBit(i: longint): byte;
var b,p: longint;
t tr 0 cho bit i trong dy bit a
1. Xc nh xem bit i nm trong byte no

125
begin
b := i shr 3;
p := i and 7; { i mod 8 }
GetBit := (a[b] shr p) and 1;
end;
b := i div 8;
2. Xc nh xem bit i l bit th my trong byte b
(tnh theo trt t 7,6,5,4,3,2,1,0)
p := i mod 8;
3. Dch a[b] qua phi p v tr, ri nhn logic
theo bit vi 00000001 ly bit phi nht (bit 0).
GetBit := (a[b] shr p) and 1;

Cc th tc c bn theo k thut x l bit khi s nh sau.
procedure Eratosthenes_B(n: longint);
var i,j: longint;
begin
fillchar(a,sizeof(a),0);
for i:=2 to round(sqrt(n)) do
for j:=i to (n div i) do
BitOn(i*j);
end;
procedure BFac(n: longint);
const bl = #32; { Dau cach }
var i,p: longint;
begin
Eratosthenes_B(n);
writeln;
for i:=2 to n do
if GetBit(i)=0 then
begin
p := Power(n,i);
if P > 0 then writeln(i,bl,p);
end;
end;
Chng trnh C#
// C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao2 {
class GiaiThua {
static byte [] a = new byte[40000];
static void Main(string[] args){
BFac(13);
Console.ReadLine();
}
static int Power(int n, int p){
int k = 0;
while (n != 0){ n /= p; k += n; }
return k;
}
static void Fac(int n) {
Console.WriteLine();
int p = 2, k;
while (p <= n){
k = Power(n,p);

126
if (k > 0) Console.WriteLine(p+" "+k);
p = NextPrime(p);
}
}
static bool IsPrime(int p){
if (p<2) return false;
if (p==2) return true;
if (p % 2 == 0) return false;
int cp = (int)(Math.Sqrt(p));
for (int i=3; i <= cp; i+=2)
if (p % i == 0) return false;
return true;
}
static int NextPrime(int p){
if (p < 2) return 2;
if (p % 2 == 0) --p;
do { p += 2; } while (!IsPrime(p));
return p;
}
// Sang Eratosthene dung byte
static void Eratosthenes(int n){
Array.Clear(a,0,a.Length);
int sn = (int)Math.Sqrt(n);
for (int i = 2; i <= sn; ++i)
if (a[i]==0){
int ni = n/i;
for (int j = i; j <= ni; ++j) a[i*j] = 1;
}
}
// Gan 1 cho bit i
static void BitOn(int i){
int b = i >> 3;
int p = i & 7;
a[b] |= (byte)(1 << p);
}
// Gan 0 cho bit i
static void BitOff(int i){
int b = i >> 3;
int p = i & 7;
a[b] &= (byte)~(1 << p);
}
// Lay tri cua bit i
static byte GetBit(int i) {
int b = i >> 3;
int p = (i & 7);
return (byte)((a[b] >> p)&1);
}
// Sang Eratosthene dung bit
static void Eratosthenes_B(int n){
Array.Clear(a, 0, a.Length);
int sn = (int)Math.Sqrt(n);
for (int i = 2; i <= sn; ++i)
if (GetBit(i) == 0) {
int ni = n / i;
for (int j = i; j <= ni; ++j) BitOn(i * j);
}
}

127
static void BFac(int n){
int p;
Eratosthenes_B(n);
for (int i = 2; i <= n; ++i)
if (GetBit(i)==0)
{
p = Power(n,i);
if (p > 0) Console.WriteLine(i+" "+p);
}
}
} // GiaiThua
} // SangTao2
phc tp
lit k cc s nguyn t t 1..N ta duyt t 1 n N , vi mi s nguyn t ta phi gch ti a
c N cc bi ca chng. Vy phc tp tnh ton c N. N .
4.4 Xp si
Cho mt bng chia li vung N dng m s 1..N tnh t trn xung v M ct m s 1..M tnh t
tri sang. Mi c php t khng qu 1 vin si. Ngi ta cho trc gii hn tng s si c php
t trn dng i l d
i
, i = 1..N v trn mi ct j l C
j
, j = 1..M. Hy tm mt phng n xp c nhiu si
nht trong bng, bit rng cc d liu u hp l v bi ton lun c nghim.
Thut ton
T chc d liu:
const MN = 101;
d: array[0..MN] of integer;
c: array[0..MN] of integer;
a: array[1..MN,1..MN] of byte;
trong d l mng cha gii hn si trn dng, c - trn ct, a l mng hai chiu biu din bng chia
li vung, a[i,j] = 1 - c vin si t ti dng i, ct j; a[i,j] = 0 - khng c si ti ny. Ta thc hin k
thut hai pha nh sau.
procedure XepSoi;
var j: integer;
begin
fillchar(a,sizeof(a),0);
d[0] := M+1; { dat linh canh }
{ Pha 1 } XepDong;
{ Pha 2 } for j := 1 to M do ChinhCot(j);
end;
Pha th nht: Xp ti a si vo mi dng. Mi dng i ta xp lin nhau d[i] vin si. ng thi ta s
dng li cc bin mng d v c vi ngha sau y: d[i] cho bit v tr ct ca vin si cui cng trn dng i.
c[j] cho bit s si cn c th xp thm trn ct j. D nhin, ta phi chnh li cc gi tr c[j] mi khi xp
thm 1 vin si vo ct ny. Nu c[j] < 0 tc l ta cn bt si ct j. Th tc xp dng khi s nh sau.
procedure XepDong;
var i,j: integer;
begin
for i := 1 to N do
for j := 1 to d[i] do
begin
a[i,j] := 1; dec(c[j]);
end;
end;

128
Pha th hai: Sau khi xp xong N dng ta tin hnh chnh tng ct j c gi tr c[j] < 0 n khi no
c[j] = 0. chnh ct j theo phng php tham lam ta duyt chn mt dng imin c cha si ti ct j v
u phi d[imin] t gi tr nh nht. Sau ta chuyn vin si trn dng imin t ct j sang ct d[imin]+1
v chnh li cc gi tr c[j] v d[imin]. tm dng imin ta cn dng phn t d[0] vi gi tr ln nht lm
phn t khi u. Ta c th cho gi tr ny l M+1, v mi dng khng th c qa M vin si. Bn cn lu
rng khi d[imin] = M tc l mi vin si cui cng trn mi dng u chim v tr ti ct M tc l ht ch
t si.
procedure ChinhCot(j: integer);
begin
while c[j] < 0 do GiamCot(j);
end;
procedure GiamCot(j: integer);
var i: integer;
begin
i := DongMin(j);
a[i,j] := 0; { Bo vien soi } inc(c[j]);
if d[i] = M then exit;
inc(d[i]); a[i,d[i]] := 1; { Dat 1 vien vao day }
dec(c[d[i]]);
end;
function DongMin(j: integer): integer;
var i,imin: integer;
begin
imin := 0;
for i:=1 to N do
if a[i,j]=1 then
if d[i] < d[imin] then imin := i;
DongMin := imin;
end;
Th d di y minh ha thut ton vi N = M = 4; d = (3,2,1,2), c = (2,2,2,2).

0 0 0 0 3 1 1 1 0 3
0 0 0 0 2 1 1 0 0 2
0 0 0 0 1 1 0 0 0 1
0 0 0 0 2 1 1 0 0 2
2 2 2 2 -2 -1 1 2
Cu hnh ban u Sau Pha 1
1 1 1 0 3 1 1 1 0 3 1 1 1 0 3
1 1 0 0 2 1 1 0 0 2 0 1 1 0 3
1 0 0 0 1 0 1 0 0 2 0 1 0 0 2
1 1 0 0 2 1 1 0 0 2 1 1 0 0 2
-2 -1 1 2 -1 -2 1 2 0 -2 0 2
Chnh ct 1

129
1 1 1 0 3 1 1 1 0 3 1 1 1 0 3
0 1 1 0 3 0 1 1 0 3 0 1 1 0 3
0 1 0 0 2 0 0 1 0 3 0 0 1 0 3
1 1 0 0 2 1 1 0 0 2 1 0 1 0 3
0 -2 0 2 0 -1 -1 2 0 0 -2 2
Chnh ct 2
1 1 1 0 3 1 1 0 1 4 1 1 0 1 4
0 1 1 0 3 0 1 1 0 3 0 1 0 1 4
0 0 1 0 3 0 0 1 0 3 0 0 1 0 3
1 0 1 0 3 1 0 1 0 3 1 0 1 0 3
0 0 -2 2 0 0 -1 1 0 0 0 0
Chnh ct 3
phc tp
Ta cn chnh M ct. Mi ct ta cn lp ti a N ln, mi ln gim c 1 vin si trong ct.
gim 1 vin si ny ta phi duyt N dng tm imin. Tng cng ta cn c MN
2
thao tc.
Chng trnh C#
// C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao2 {
class XepSoi {
const int n = 4, m = 4;
static byte [,] a = new byte[n+1,m+1];
static int [] d = new int [n+1] {0,3,2,1,2};
static int [] c = new int [m+1] {0,2,1,2,3};
static void Main(string[] args) {
Xep(); Show();
Console.ReadLine();
}
static void Show(){
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= m; ++j)
Console.Write(a[i, j]);
Console.WriteLine();
}
}
static void Xep(){
Array.Clear(a,0,a.Length);
d[0] = m+1;

130
XepDong();
for (int j = 1; j <= m; ++j) ChinhCot(j);
}
static void XepDong(){
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= d[i];++j){
a[i,j] = 1; --c[j];
}
}
static void ChinhCot(int j) {
while (c[j] < 0) GiamCot(j);
}
static void GiamCot(int j){
int i = DongMin(j);
a[i,j] = 0; // Bot 1 vien tai o (i,j)
++c[j];
if (d[i]==m) return; // het cho dat tren dong i
++d[i]; a[i,d[i]] = 1; // Dat 1 vien vao o (i,d[i])
--c[d[i]];
}
static int DongMin(int j){
int imin = 0;
for (int i = 1; i <= n; ++i)
if (a[i,j]==1)
if (d[i] < d[imin]) imin = i;
return imin;
}
} // XepSoi
} // SangTao2
4.5 Dy cc hon v
Dy cc hon v ca N ch ci HOA u tin trong bng ch ting Anh c sp theo trt t t
in tng dn v vit lin nhau thnh mt dy k t duy nht. Hy cho bit k t th M trong dy tnh t 1
tr i, 2 s N s 10, 1 s M s N.N!. Th d, vi N=3, ta c dy 6 hon v xp theo trt t t in l ABC, ACB,
BAC, BCA, CAB, CBA. Sau khi ghp chng ta thu c dy duy nht gm 18 k t
ABCACBBACBCACABCBA. K t th M = 15 trong dy l: B.
Thut ton
Nu ta vit mi hon v trn 1 dng th k t th M s nm trn dng d = (M-1) div N (tnh t dng
0) v s chim v tr v = ((M-1) mod N)+1 (tnh t 1) trn dng d . Nh vy ta cn xc nh hon v trn
dng d ri ly k t nm v tr v lm kt qu.
xc nh hon v (c
1
,c
2
,...,c
N
) ti dng d ta ln lt tnh cc k t c
i
, i = 1..N. Ta phn hoch cc
hon v theo nhm. Nu b k t u tin th ta cn li (N-1)! hon v, khi hon v ti dng d s ri vo
nhm d div (N-1)! v s chim dng d mod (N-1)! trong nhm . Tng t, ta tnh cho cc k t th 2, 3,
..., N-1. K t cn li s chim v tr th N. Nu bit nhm d ca k t th i trong hon v th ta tnh c
chnh k t nh sau.
d = 1 ng vi k t th nht trong s cc k t cha dng,
d = 2 ng vi k t th hai trong s cc k t cha dng,
...
Tng qut, d ng vi k t th d trong s cc k t cha dng.
Mi ln xc nh c k t no th ta nh du k t bng th tc Mark.
trnh vic tnh n! ta vit th tc ThuongDu(z, n, q, r) cho ra thng q v d r ca php chia s t
nhin z cho n!, c th l q = z div n! v r = z mod n!. Th tc ny kh n gin. Ta c

131
q
1
= z div n; r
1
= z mod n z = q
1
.n + r
1
;
q
2
= q
1
div (n-1); r
2
= q
1
mod (n-1) q
1
= q
2
.(n-1) + r
2
;

q
n-1
= q
n-2
div 2; r
n-1
= q
n-2
mod 2 q
n-2
= q
n-1
.2 + r
n-1
.
q
n
= q
n-1
div 1 = q
n-1
; r
n
= q
n-1
mod 1 = 0.
Thay ln lt cc i lng ca dng di vo dng trn ta thu c q = q
n-1
v r = r
1
+ n.r
2
+ (n-
1).r
3
++ 3.r
n-1
+ 2.r
n
. Nhn xt ny cho php ta xy dng th tc theo k thut chia lin tip nh sau.
procedure ThuongDu(z,n: longint;var q,r: longint);
var c: longint;
begin
r := 0; q := z; c := 1;
while n > 1 do
begin
r := r + (q mod n)*c;
q := q div n;
c := n; n := n - 1;
end;
end;
Th tc Test trong chng trnh di y tnh mi xut hin ca cc k t (M = 1..24*4) trong dy
cc hon v vi N = 4.
Chng trnh Pascal
(* Pascal *)
uses crt;
const MN = 20; bl = #32;
var b: array[0..MN] of byte;
{ d = z div n! r = z mod n! }
procedure ThuongDu(z,n: longint;var q,r: longint);
T vit
{ Danh dau ki tu v thu k
trong so cac ki tu chua dung }
procedure Mark(N,k,v: integer);
var i,d: integer;
begin
d := 0;
for i := 1 to N do
if b[i] = 0 then
begin
d := d+1;
if d = k then
begin
b[i] := v;
exit;
end;
end;
end;
{ Xac dinh ki tu thu M trong day cac hoan vi }
function Value(N: integer;M: longint): char;
var i,j,v: integer;
th,du,d: longint;
begin
fillchar(b,sizeof(b),0);
d := (M-1) div N; { Dong chua ki tu M }

132
v := (M-1) mod N + 1; { vi tri cua M tren dong d }
{ xac dinh hoan vi tai dong d }
j := N-1;
for i := 1 to N-1 do
begin
ThuongDu(d,j,th,du);
Mark(N, th+1,i);
j := j-1;
d := du;
end;
Mark(N,1,N);
for i:=1 to N do
if b[i] = v then
begin
Value := chr(ord('A') + i-1);
exit;
end;
end;
procedure Test;
var N: integer;
M: longint;
begin
N := 4; writeln;
for M := 1 to 24*N do
begin
write(Value(N,M));
if M mod N = 0 then
begin
if readkey = #27 then halt else writeln;
end;
end;
end;

BEGIN
Test;
END.
Chng trnh C#
// C#
using System;
using System.Collections.Generic;
using System.Text;

namespace SangTao2 {
class DayHoanVi {
const int MN = 20;
static int [] b = new int [MN+1];
static void Main(string[] args){
Test();
}
// q = z / n!; r = z % n!
static void ThuongDu(long z, int n,
out long q, out long r ){
q = z; r = 0;
int c = 1;

133
while (n > 1){
r += (q % n) * c;
q /= n;
c = n; --n;
}
}
static void Mark(int n, long k, int v){
int d = 0;
for (int i = 1; i <= n; ++i)
if (b[i]==0){
++d;
if (d==k){ b[i] = v; return; }
}
}
static char Value(int n, long m){
Array.Clear(b, 0, b.Length);
long d = (int) (m - 1) / n;
// d - Dong chua ki tu can tim
int v = (int)(m - 1) % n + 1;
// v - vi tri cua ki tu tren dong d
int j = n - 1;
long th, du;
for (int i = 1; i < n; ++i){
ThuongDu(d, j, out th, out du);
Mark(n, th + 1, i);
d = du; --j;
}
Mark(n, 1, n);
for (int i = 1; i <= n; ++i)
if (b[i]==v) return (char)('A'+i-1);
return (char)0;
}
// test voi n=4, m=1..n.n!
static void Test(){
int n = 4;
int m4 = 24 * n;
string s;
for (long m = 1; m <= m4; ++m) {
Console.Write(Value(n, m));
if (m % n == 0){
s = Console.ReadLine();
if (s == "stop") break;
}
}
}
} // DayHoanVi
} // SangTao2


N N! N N!
1
2
3
4
1
2
6
24
1
1
1
2
39916800
479001600
6227020800
87178291200

134
5
6
7
8
9
1
0

120
720
5040
40320
362880
362880
0
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
1307674368000
20922789888000
355687428096000
6402373705728000
121645100408832000
243290200817664000
0

Giai tha ca 20 s nguyn dng u
tin


Vi C# bn c th dng kiu int64 hoc long vi 64 bit (8 byte) biu din s nguyn trong khong
[-9.223.372.036.854.775.808, 9.223.372.036.854.775.807].
phc tp
Thut ton ch i hi N = 20 php chia cc s nguyn c ti a 20 ch s v gi th tc Mark N
ln, mi ln gi phi thc hin php duyt trn dy N phn t. Tng cng l N
2
php ton, tc l c 400
php ton thay v 2432902008176640000 php ton nu ta sinh ln lt N! hon v bng phng php vt
cn vi N = 20.
4.6 B bi
Trn bn t mt b bi gm n-1 qun bi m s 1,2,,n-1, 3 s n s 10000. Trng ti ch nh bn
ly k qun bi. Sau trng ti a ra mt s t nhin s. Bn cn c gng thc hin t nht m thao tc
thuc mt trong hai loi sau y:
- Ly thm mt qun bi t trn bn,
- B bt mt qun bi trn tay,
cui cng t c h thc
t mod n = s mod n (*)
trong t l tng s hiu cc qun bi c trn tay bn sau khi bn hon tt m thao tc nh trn.
D liu vo: file vn bn BAI.INP
Dng u tin: 3 s t nhin n, k v s.
T dng th hai tr i: k s t nhin th hin m s ca cc qun bi cn ly lc u.
D liu ra: Hin th trn mn hnh
Dng u tin: s t nhin m cho bit s thao tc t nht cn thc hin
Tip n l m dng, mi dng l mt thao tc ly thm hoc b bt mt qun bi v. v > 0 cho bit
cn ly thm (t trn bn) qun bi v; v < 0 cho bit cn bt (t trn tay) qun bi v t c h thc
(*).
Th d, vi n = 8, trng ti cho s s = 22 v ch nh bn ly k = 3 qun bi l 2, 3 v 6.

135
Nu bn b qun bi 2 v ly qun bi 5 th tng t = 3 + 6 + 5 = 14. Khi
t mod n = 14 mod 8 = 6 = s mod n = 22 mod 8.
Vy mt li gii cho b d liu ny l
Thc hin 2 thao tc: 2 v +5

BAI.INP MN HNH NGHA
8 3 22
2 3 6

2
-2
5
Cho b bi gm 8 qun. Lc u trng ti ch nh bn ly k = 3 qun bi
m s 2, 3 v 6. Ngoi ra trng ti a ra s s = 22.
Sau bn thc hin 2 thao tc
- b qun bi 2
- ly thm qun bi 5.
Khi tng s hiu cc qun bi c trn tay bn s l:
T = 3 + 6 + 5 = 14
T mod N = 14 mod 8 = 6 = s mod 8 = 22 mod 8.




n = 8; s = 22; Trn tay gi k = 3 qun bi 2, 3, 6.
Li gii: B qun bi 2, ly thm qun bi 5.
t = 3+6+5 = 14,
t mod 8 = 14 mod 8 = 6 = s mod 8 = 22 mod 8.

Thut ton
Ta s chng minh rng vi khng qu 2 thao tc (+) ly thm / () b bt mt qun bi ta c th t
c h thc (*).
Trc ht ta nhc li cc php ton ng d. Vi s nguyn dng n cho trc ta xt tp cc s d
trong php chia mt s t nhin x cho n, x mod n, Z
n
= {0,1,2,,n-1}. Trn Z
n
cc php ton cng v nhn
c thc hin nh bnh thng sau ly kt qu chia d cho n. Php ton ly s i ca s x cho ta nx.
Php tr xy c i thnh php cng x vi s i ca y. Ta c
Cng: (x + y) mod n
2 3 6
5

136
Nhn: x*y mod n
Ly s i ca x: n x
Tr: (x + (ny)) mod n.
Hy tng tng cc s ca Z
n
l 0, 1, , n-1 c b tr trn mt vng trn nh trn mt ng h.
tnh tng x+y ta xut pht t x v di chuyn y bc theo chiu kim ng h (cn gi l di chuyn xui),
mi bc ta chuyn qua mt s. Kt qu s l im dng cui cng. tnh hiu x y ta cng xut pht t
x v di chuyn y bc theo chiu ngc li (di chuyn ngc). rng, trn vng trn gm n s, di
chuyn xui y bc s cho cng kt qu nh di chuyn ngc (ny) bc, v ngc li, di chuyn ngc y
bc s tng ng nh di chuyn xui (ny) bc. iu ny c ngha l mun thm b n v cho i
lng t ta c th bt (nb) n v v ngc li, mun bt b n v t i lng t ta c th thm cho t (nb)
n v. Ta cng rng s hiu ca mi qun bi u nh thua n v mi qun bi hoc l c trn tay
ngi chi, hoc l nm trn bn. V l trn, i khi ngi ta ni tnh ton theo ng d (modulo) chnh l
tnh ton trn vng trn.
Bn cng cn ghi nh tnh cht sau y:
Vi mi s t nhin x, y v n, n > 0 v vi mi php ton s hc u e {+, ,*} ta lun c
(x u y) mod n = ((x mod n) u (y mod n)) mod n
Cng thc trn cho ta quy tc d hiu sau y: Khi tnh tr ca cc biu thc s hc ch cha cc
php ton cng, tr v nhn trong Z
n
ta c th thc hin php ly s d mod n trn cc hng t v cc kt
qu trung gian.
V ly tha nguyn dng tng ng vi php nhn lin tip, ta suy ra h qu sau:
a
k
mod n = (a mod n)
k
mod n
Sau khi bit cc gi tr input l n, k, s v s hiu cc qun bi cn ly ln tay, ta gn tr cho mng
a[1..n1] nh sau: a[i] = 1 cho bit qun bi i c trn tay, ngc li, a[i] = 0 cho bit qun bi i cn nm
trn bn. Vi th d cho, trng ti yu cu ta ly 3 qun bi c s hiu 2, 3 v 6 nn a = (0,1,1,0,0,1,0)
ng vi a[2] = a[3] = a[6] = 1, cc gi tr a[i] cn li u bng 0.
Trc ht ta tnh tng s hiu ca cc qun bi c trong tay lc u v t trong bin t. Sau ta
tnh t := t mod n v s := s mod n. Vi th d cho ta tnh c
t = 2+3+6 = 11, do t mod n = t mod 8 = 3
v s mod 8 = 22 mod 8 = 6
Tc l t = 3 v s = 6.
Gi s t > s, ta t b = t s v xt cc trng hp loi tr nhau sau y:
1. b = 0: H thc (*) tha, ta khng phi lm g. Ta thng bo m = 0, trong m l s thao
tc +/ cn thc hin.
2. Qun bi b c trn tay, tc l a[b] = 1: Ta ch vic b qun bi ny xung, khi tng t s
gim b n v theo mod n.
3. Qun bi (nb) c trn bn, tc l a[nb] = 0: Ta ch vic ly thm qun bi ny. Khi tng
t s c thm (n-b) n v theo mod n, iu ny tng ng vi vic gim tng t i b n v theo mod n.
4. Nu khng xy ra cc trng hp 1, 2 v 3 nh trn, tc l b = 0, a[b] = 0, a[nb] = 1, ta tin
hnh nh sau:
Tm hai qun bi u v v tha cc iu kin sau
Qun bi u c trn tay, a[u] = 1,
Qun bi v c trn bn, a[v] = 0,
u = (k*b) mod n; v = ((k1)*b) mod n, k l mt s t nhin. iu ny c ngha l u ln hn v b n
v theo mod n.
Nu tm c hai qun bi u v v nh trn ta s thc hin hai thao tc: b qun bi u (u) v ly
thm qun bi v (+v). Khi tng t s c gim mt lng b theo mod n. Tht vy,
(u v) mod n = (k*b (k1)*b) mod n = b.

137
Trng hp t < s ta phi thm b = s t n v cho cho t. Vic ny tng ng vi gim t bt (n-b)
n v. t b = n-b ri lp li th tc trn s cho ta kt qu tng ng.
Ta chng minh rng nu gp tnh hung 4 th bao gi cng c th tm c hai qun bi u v v nh
m t. Trn hai ngn nm trc nh ton hc C Hy Lp Diophantus pht biu v chng minh nh l
sau:
nh l Cho phng trnh ax mod n = b mod n, vi cc h s a, b, n l cc s t nhin, n > 0. Gi d
l c chung ln nht ca a v n, d = (a,n). Khi
a) Nu d khng l c ca b th phng trnh v nghim.
b) Nu b = kd th phng trnh c ng d nghim trong tp Z
n
. Cc nghim ny c dng (x +
i(n/d) ) mod n, trong x l mt nghim ty , i = 0,1,2...(d-1).
Phng trnh ax mod n = b mod n c ngi i sau gi l phng trnh Diophantus.
Chng minh
Nu x l nghim ca phng trnh ax mod n = b mod n th ax v b c cng s d theo mod n nn
hiu ca chng s chia ht cho n, ax b = kn, hay ax kn = b. Mt khc, do d = (a,n) nn a v n u chia
ht cho d v do hiu axkn cng chia ht cho d, th tc l b phi chia ht cho d. Gi s b = md tc l
phng trnh c nghim. Gi x l nghim nguyn khng m nh nht ca phng trnh trn, ta d dng
kim tra c rng x+i(n/d), i = 0,1,,(d1) cng l nghim ca phng trnh . Tht vy, ta rng
nu d l c chung ln nht ca a v n th an/d chnh l bi chung nh nht ca chng, ngha l an/d chia
ht cho a v n. Ta c
a(x+i(n/d)) mod n = ((ax mod n) + (i(an)/d) mod n) mod n
= (b mod n + 0) mod n = b mod n.
Ta chng minh xong.
Th d 1. Gii phng trnh sau
6x mod 9 = 21 mod 9
Phng trnh trn tng ng vi phng trnh sau:
6x mod 9 = 3
Ta c d = (6,9) = 3. V 3 l c ca v phi nn phng trnh cho c 3 nghim. D thy x = 2 l
mt nghim ca phng trnh. Vy cc nghim ca phng trnh di dng tng qut l
x + i(n/d) = 2 + i(9/3) = 2 + 3i, i = 0, 1, 2
C th l x
1
= 2, x
2
= 5 v x
3
= 8 l 3 nghim trong tp Z
9
= {0, 1, 2, 3, 4, 5, 6, 7, 8}.
Th d 2. Gii phng trnh
4x mod 12 = 5
Ta c, d = (4,12) = 4 khng phi l c ca 5. Phng trnh v nghim.
Tr li bi ton trn, khi gp tnh hung 4 ta c a[b] = 0 v a[nb] = 1. Xt phng trnh bx mod n
= (nb) mod n. V 1 s b < n nn 1 s nb < n v do (nb) mod n = nb, phng trnh cho c th vit
li l bx mod n = nb.
Theo tnh cht: c chung ln nht ca hai s t nhin (a,b) s khng i nu ta thay s ln nht
trong hai s bng hiu ca n vi s th hai, t d = (b,n), ta c d = (b,nb), tc l nb chia ht cho d,
do phng trnh bx mod n = nb lun c nghim. T nhn xt ny suy ra rng vng lp repeat trong
on trnh di y lun kt thc.
u := b;
repeat
v := u;
u := (u+b) mod n;
until a[u] = 1;
Tht vy, sau k ln lp ta thu c u = kb do phng trnh bx mod n = nb c nghim nn s tn ti
mt gi tr k u = kb mod n = nb. Do a[nb] = 1 nn ti a sau k ln lp th vng lp phi kt thc v ta
s thu c u = kb mod n. V v mang gi tr st trc ca u nn v = (k1)b mod n.
Ta c thut ton sau y

138
1. c d liu vo cc bin n, k v s
2. Khi tr cho mng a[1..n1] vi a[i] = 1 nu qun bi i c trn tay, a[i] = 0 nu qun bi i cn trn
bn.
3. Tnh t = tng s hiu cc qun bi c trn tay.
4. Tnh t := t mod n; s := s mod n.
5. Nu t > s: t b := t s; ngc li t b := n (s t).
ngha: cn gim b n v t tng t t h thc
t mod n = s mod n (*)
6. Xt cc trng hp loi tr nhau sau y
6.1 b = 0: t m = 0; Thng bo: Khng lm g; Stop.
6.2 a[b] = 1 (Qun bi b c trn tay):
Thng bo: Thc hin m = 1 thao tc b: B qun bi b; Stop.
6.3 a[b] = 0 v a[nb] = 0 (Qun bi b khng c trn tay, qun bi (n-b) c trn bn):
Thng bo: Thc hin m = 1 thao tc +(nb): Ly qun bi (nb); Stop.
6.4 a[b] = 0 v a[nb] = 1: (Qun bi b khng c trn tay, qun bi (n-b) khng c trn bn)
6.4.1 Tnh u v v
u := b;
repeat
v := u;
u := (u+b) mod n;
until a[u] = 1;
6.4.2 Thng bo: Thc hin m = 2 thao tc
u: B qun bi u
+v: Ly qun bi v.
6.4.3 Stop

T chng minh trn ta rt ra phc tp ca thut ton l O(n) v trong trng hp xu nht ta
duyt 1 ln mng a cha n-1 phn t.
T chc d liu:
const mn = 10000; { Max n }
bl = #32; { Du cch }
nl = #13#10; { New line: xung dng }
ESC = #27;
fn = 'bai.inp';
type mi1 = array[0..mn] of integer;
var a: mi1; { Dnh du cc qun bi }
n, k : integer; { n1: s lng qun bi }
{ k: s lng cc qun bi trn tay }
t , s: longint; { t: tng s hiu cc qun bi trn tay }
{ s: s i chng ca trng ti }
f: text; { input file }
Th tc c d liu: M input file, c cc gi tr n, k v s, c s hiu v nh du k qun bi c
chn. tnh tng t ca chng }
procedure Doc;
var i,j: integer;
begin
assign(f,fn); reset(f);
read(f,n,k,s);
t := 0; fillchar(a,sizeof(a),0);
for i := 1 to k do
begin
read(f,j); a[j] := 1; t := t+j;
end;
close(f);

139
end;
Th tc x l.
procedure XuLi;
var b,u,v: integer;
begin
t := t mod n; s := s mod n;
if t >= s then b := t-s else b := n-(s-t);
if (b = 0) then
begin
Ket(0,0,0);
exit
end;
if (a[b] = 1) then
begin { Quan bai b co tren tay }
Ket(1,-b,0); { bo xuong }
exit
end;
if (a[n-b] = 0) then
begin { Quan bai n-b co tren ban }
Ket(1,n-b,0); { Lay len }
exit
end;
{ Quan bai b khong co tren tay
Quan bai n-b khong co tren ban }
u := b;
repeat
v := u;
u := (u+b) mod n;
until (a[u] = 1);
Ket(2,-u,v); { bo u, lay v }
end;
Th tc Ket(m,u,v) thng bo kt qu ng vi cc trng hp:
m = 1: B bt hoc ly thm 1 qun bi u;
m = 2: B qun bi u, ly qun bi v.
procedure Ket(m,u,v: integer);
begin
case m of
0: write(nl,'Khong lam gi',nl);
1: begin
write(nl,' Thuc hien 1 thao tac: ');
if (u > 0) then write('+',u,nl)
else write(u,nl);
end;
2: begin
write(nl,' Thuc hien 2 thao tac: ');
if (u > 0) then write('+',u,bl)
else write(u,bl);
if (v > 0) then write('+',v,nl)
else write(v,nl);
end;
end;
end;
phc tp tnh ton: N.
Chng trnh C# di y hin th kt qu trn mn hnh.

140
Chng trnh C#
// C#
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace SangTao2 {
class BoBai {
const string fn = "bai.inp";
const int MN = 20;
static int[] a;
static int n; // so luong quan bai
static int k; // so luong quan bai tren tay
static int s; // so cho truoc trong khoang [1,n];
static int t;
static void Main(string[] args){
Doc(); XuLi();
Console.ReadLine();
}
static void Doc(){
int[] c =
Array.ConvertAll((File.ReadAllText(fn)).Split(
new char[] { '\0', '\n', '\t', '\r', ' ' },
StringSplitOptions.RemoveEmptyEntries),
new Converter<String, int>(int.Parse));
n = c[0]; // so luong quan bai
k = c[1]; // so luong quan bai tren tay
s = c[2]; // so cho truoc
a = new int[n + 1];
Array.Clear(a, 0, a.Length);
t = 0;
for (int i = 3; i < c.Length; ++i){
a[c[i]] = 1; t += c[i];
};
}
static void XuLi(){
t %= n; s %= n;
int b = (t >= s) ? t - s : n - (s - t);
if (b == 0) { Ket(0, 0, 0); return; }
// Sua t: giam b don vi hoac tang n-b don vi
if (a[b] == 1) { // quan b co tren tay
Ket(1, -b, 0); // bo quan b
return;
}
if (a[n - b] == 0) { // quan n-b co tren ban
Ket(1, n - b, 0); // lay quan n-b
return;
}
// Quan b tren ban, quan n-b trn tay
int u = b, v = 0;
do { v = u; u = (u + b) % n; } while(a[u] == 0);
Ket(2, -u, v); // bo quan u, lay quan v
}
static void Ket(int c, int u, int v) {
switch (c){

141
case 0: Console.WriteLine(c); break;
case 1: Console.WriteLine(c + ": " + u); break;
case 2: Console.WriteLine(c + ": "+u+" , "+v);
break;
}
}
} // Bo Bai
} // SangTao2
4.7 Thun th
Dijkstra E.
Cho hon v a = (a
1
,a
2
,...,a
N
) ca N s nguyn dng u tin 1,2,...,N. Mt thun th ca a l dy b
= (b
1
,b
2
,...,b
N
) trong b
i
l s lng cc phn t nh thua a
i
v ng trc a
i
, b
i
= ||{a
j
| a
j
< a
i
, j < i}||.
Bit trc N, 2 s N s 1000.
a) Cho mt hon v a, tnh thun th b ca a.
b) Cho thun th b, tm han v a.
c) Mi thun th u c phn t u tin (tri nht) l 0 nn ta c th b phn t ny. Ngoi ra, nu
trong thun th cn c phn t 0 na ta b thm 1 phn t 0 thu c mt dy c M = N-1 hoc M = N-
2 phn t v gi dy ny l thun th thu gn c. Cho mt thun th thu gn. Hy tm hon v nh nht theo
trt t t in sinh ra thun th thu gn ny.
Th d, vi N = 5,
a) Cho a = (2,5,1,4,3) ta tnh c b = (0,1,0,2,2),
b) Cho b = (0,1,0,2,2) ta tm c a = (2,5,1,4,3),
c) Cho thun th thu gn c = (1,2,2), N = 5, ta tm c a = (2,3,5,4,1).
rng hai hon v (2,5,1,4,3) v (2,3,5,4,1) cng sinh ra thun th thu gn (1,2,2), nhng
hon v (2,3,5,4,1) nh hn.
D liu vo: text file THUANTHE.INP
Dng u tin: N
T dng th hai tr i: N phn t ca hon v a.
Dng tip theo: M
Trn cc dng tip theo: M phn t ca thun th thu gn.
D liu trn cng mt dng cch nhau qua du cch.
D liu ra: Hin th trn mn hnh theo trt t sau:
Cu a: Cho hon v a, tm thun th b.
Cu b: Cho thun th b, tm hon v a.
Cu c: Cho thun th thu gn c tm hon v nh nht a.
Thut ton
Vic xc nh thun th b t hon v a l d dng. Hai cu b v c l hi kh. Chng ta s s dng k
thut i xng trnh by mt thut ton do Dijkstra xut. Theo thut ton ny th th tc cho cu a v
b l i xng nhau. Thut ton tin hnh x l ti ch, ngha l khng s dng mng ph m trc tip bin
i hon v a thnh thun th lu lun trong a v ngc li.
Trc ht ta nhn xt rng vi hon v n v e = (1,2,...,N) th c ng e
i
phn t khng ln hn e
i

v khng ng sau phn t e
i
, i = 1..N. Vy, nu trong mt hon v a m ta thy mt phn t a
j
> a
i
v j s i
th ta khng nh rng ch cn ng a
j
-1 phn t khng ln hn a
j
v khng ng sau phn t a
j
.
Ta khai bo cc bin x, y, a l cc mng cha cc hon v v thun th:
const MN = 1000;
type mi1 = array[0..MN] of integer;
var x,y,a: mi1;
Th tc bin i hon v a sang thun th a khi s nh sau:

142
procedure HoanViThuanThe(var a: mi1;n: integer);
var i,j: integer;
begin
for i := n downto 1 do
for j:=1 to i do
if (a[j] >= a[i]) then dec(a[j]);
end;
thu c hon v a t thun th a ta ch cn vit th tc x l theo chiu ngc li. Hai th tc
nh vy gi l i xng nhau.
procedure ThuanTheHoanVi(var a: mi1;n: integer);
var i,j: integer;
begin
for i := 1 to n do
for j := i downto 1 do
if (a[j] >= a[i]) then inc(a[j]);
end;
Hai th tc ny u c phc tp N
2
.
Cu c c gii nh sau. trc ht thm mt s 0 vo u tri ca d liu vo a. Sau xt hiu N-
M. Nu N-M=1 th chng t thun th thu gn a ch khuyt mt s 0. Ta ch vic gi th tc
ThuanTheHoanVi(a,N) l thu c kt qu. Trng hp N-M=2 th ta phi b thm mt s 0 na vo
mt v tr no trong a. Ta ln lt t s 0 ny vo u phi (v tr N) ri chuyn dn n v u tri, mi
ln mt v tr v gi th tc ThuanTheHoanVi sinh ra mt dy a[1..N] sau kim tra xem dy ny
c phi l hon v ca 1..N hay khng. Nu ng, ta dng thut ton v cho ra kt qu. kim tra mt dy
a[1..N] c phi l mt hon v ca 1..N ta s dng mt mng d[1..N] nh du xem mi phn t a[i] c xut
hin ng 1 ln hay khng. Tuy nhin trc ta phi kim tra iu kin 1 s a[i] s N m bo rng a[i]
nm trong gii hn ca ch s mng d.
procedure ThuanTheThuGon(var a: mi1; n,m: integer);
var b: mi1;
i: integer;
begin
move(a[1],a[2],m*sizeof(integer));
a[1] := 0; inc(m);
if (n = m) then
begin
ThuanTheHoanVi(a,n);
exit;
end;
b := a;
for i := n downto 2 do
begin
{ Them 0 tai vi tri i }
a := b;
move(a[i],a[i+1],(n-i)*sizeof(integer));
a[i] := 0;
ThuanTheHoanVi(a,n);
if LaHoanVi(a,n) then exit;
end;
end;
function LaHoanVi(var a: mi1; n: integer): Boolean;
var d: mi1;
i: integer;
begin
LaHoanVi := false;
fillchar(d,sizeof(d),0);
for i := 1 to n do

143
begin
if (a[i] < 1) or (a[i] > n) then exit;
if (d[a[i]] = 1) then exit;
d[a[i]] := 1;
end;
LaHoanVi := true;
end;
Chng trnh C#
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System;
namespace SangTao2 {
class ThuanThe {
const string fn = "thuanthe.inp";
const int MN = 1001;
static int[] a = new int[MN];
static int[] c = new int[MN];
static int n; // 1..n
static int m; // so luong phan tu trong thuan the thu gon
static void Main(string[] args){
Doc();
Console.WriteLine("\n n = " + n + " m = " + m);
Console.WriteLine("\n Cho Hoan vi: ");
Show(a, n);
HoanViThuanThe(a);
Console.WriteLine("\n Tim Thuan the: ");
Show(a, n);
Console.WriteLine("\n Cho Thuan the: ");
Show(a, n);
ThuanTheHoanVi(a);
Console.WriteLine("\n Tim Hoan vi: ");
Show(a, n);
Console.WriteLine("\n Cho Thuan the Thu gon: ");
Show(c,m);
ThuanTheThuGon(c);
Console.WriteLine("\n Tim Hoan vi: ");
Show(c, n);
Console.ReadLine();
}
static void Doc(){
int[] v =
Array.ConvertAll((File.ReadAllText(fn)).Split(
new char[] { '\0', '\n', '\t', '\r', ' ' },
StringSplitOptions.RemoveEmptyEntries),
new Converter<String, int>(int.Parse));
int i = 0;
n = v[i++];
for (int j = 1; j <= n; ++j) a[j] = v[i++];
m = v[i++];
for (int j = 1; j <= m; ++j) c[j] = v[i++];
}
static void HoanViThuanThe(int[] a){
for (int i = n; i > 0; --i)

144
for (int j = 1; j <= i; ++j)
if (a[j] >= a[i]) --a[j];
}
static void ThuanTheHoanVi(int[] a){
for (int i = 1; i <= n; ++i)
for (int j = i; j > 0; --j)
if (a[j] >= a[i]) ++a[j];
}
static void ThuanTheThuGon(int[] c){
Array.Copy(c, 1, c, 2, m);
c[1] = 0; ++m;
if (m == n) { ThuanTheHoanVi(c); return; }
int [] b = new int [n+1];
Array.Copy(c,1,b,1,m);
for (int i = n; i >= 2 ; --i){
Array.Copy(b,1,c,1,i-1);
Array.Copy(b, i, c, i + 1, m - i + 1);
c[i] = 0;
ThuanTheHoanVi(c);
if (LaHoanVi(c)) return;
}
}
static bool LaHoanVi(int[] c){
int[] d = new int[n + 1];
Array.Clear(d,0,d.Length);
for (int i = 1; i <= n; ++i)
{
if (c[i] < 1 || c[i] > n) return false;
if (d[c[i]] > 0) return false;
d[c[i]] = 1;
}
return true;
}
static void Show(int[] a, int n){
for (int i = 1; i <= n; ++i)
Console.Write(a[i] + " ");
}
} // ThuanThe
} // SangTao2
phc tp
Th tc move(a,b,M) copy m byte t mng a sang mng b. Th tc ThuanTheThuGon c phc
tp N
3
v n gi th tc ThuanTheHoanVi N ln. Hm kim tra mt dy a[1..N] c phi l hon v i hi
N thao tc v s dng mt mng ph d nh du cc phn t xut hin.

4.8 Cc nh khoa hc
Olimpic Quc t
Trong mt hi ngh khoa hc c n nh khoa hc (KH) t chc th gin di hnh thc sau. H t
mt my tnh trong cn phng hp, ngoi my ra ch c th cha thm 1 ngi, mn hnh my tnh hin s
0. Sau mi nh khoa hc buc phi thc hin n thao tc loi 1 v n thao tc loi 2 an xen nhau, trong
thao tc u tin phi l loi 1.

Thao tc loi 1: c Thao tc loi 2: Ghi

145
Vo phng;
c v ghi nh s trn mn hnh;
Ra khi phng.
Vo phng;
Ly s nh trong u cng thm 1 v hin th
kt qu trn mn hnh;
Ra khi phng.

Khi hin th s mi trn mn hnh th s c trn mn hnh t ng b xa v ngi thc hin thao
tc loi 2 cng qun lun s nh.
Cho trc cc gi tr n v m. Hy b tr mt lch thc hin cc nh khoa hc hon thnh trn vn
cuc chi theo ng yu cu v s cui cng hin th trn mn hnh l m.
D liu vo: Tp vn bn KH.INP cha 2 s n v m trn mt dng cch nhau qua du cch.
D liu ra: Tp vn bn KH.OUT cha mt lch thc hin gm mt dy tun t cc dng lnh thuc
mt trong hai dng sau:
Dng th nht gm hai s t nhin ghi cch nhau qua du cch, i t cho bit nh khoa hc i thc
hin thao tc t; i e {1,2,,n}; t e {1,2}.
Dng th hai gm 4 s t nhin ghi cch nhau qua du cch, i t
1
t
2
k cho bit nh khoa hc i thc
hin k ln lin tip cc thao tc t
1
v t
2
an xen nhau; i e {1,2,,n}; t e {1,2}; k > 0.
Nu khng c cch no b tr lch th ghi duy nht mt s 0.
Th d,

KH.INP KH.OUT ngha
3 4

1 1
3 1 2 3
1 2
2 1
1 1 2 2
2 2
2 1 2 2


C 3 nh khoa hc tham gia tr chi th gin vi nhim v sinh ra
kt qu trn mn hnh (MH) l s 4. Lch thc hin s nh sau:
Ngi s 1: c. MH = 0. u(1) = 0.
Ngi s 3: (c; Ghi) 3 ln. MH = 3.
Ngi s 1: Ghi. MH = u(1)+1 = 0+1 = 1.
Ngi s 2: c. u(2) = 1, MH = 1.
Ngi s 1: (c; Ghi) 2 ln. MH = 3.
Ngi s 2 Ghi. MH = u(2)+1 = 1+1 = 2.
Ngi s 2 (c;Ghi) 2 ln. MH = 2+2 = 4.
Ch thch: u(i) - s nh trong u nh khoa hc th i.
Thut ton
Ta s ch ra rng vi mi n > 2 v mi m trong khong 2..n
2
lun lun c mt lch tha yu cu ca
u bi (ta gi l lch hp l) mn hnh (MH) t gi tr m.
Sau khi m tp KH.INP v c hai gi tr n, m ta tin hnh xp lch v ghi dn kt qu vo tp
KH.OUT m sn. Trc ht ta nhn xt rng nu mt ngi thc hin lin tip k ln mt cp thao tc (c
- Ghi, vit tt l G), tc l sau 2k dng lnh
i 1
i 2
...
i 1
i 2
th gi tr ca MH c tng thm k n v. Dy 2k lnh trn c th vit gp li thnh mt lnh 4
thnh phn l i 1 2 k.

146
Ta tnh k = m div n v r = m mod n, ta c m = k.n+r , 0 s r < n, vi ngha l t c gi tr m
trn MH th phi c k ngi thc hin y v lin tip n cp thao tc G, ngoi ra phi c t nht mt
ngi thc hin thm r cp thao tc G. Do yu cu mi ngi buc phi thc hin n thao tc v n thao
tc G, mt l t nhin, ta phi s dng 2 ngi ghi nhn gi tr hin c trn MH khi cn s tr li gi tr
(d nhin l phi cng thm 1) nhm m bo cho cc thao tc cn thit c thc hin lin tc. Xt 3
trng hp sau y.
Trng hp 1: r = 0, tc l m = k.n. Ta cn k ngi thc hin lin tip n cp thao tc G. Tuy
nhin, do nhng ngi khc cng phi thc hin y n cp thao tc G cho mi ngi, nn ta chia cc
thao tc thnh hai loi l cc thao tc v ch l nhng thao tc n mt thi im no s c mt thao tc
khc t li gi tr cho MH. Cc thao tc cn li c gi l thao tc c ch. Nh vy trng hp ny cn
c k ngi thc hin tng cng m = k.n cp thao tc c ch v mi thao tc cn li l v ch. Lch khi s
nh sau.
1 1 - Ngi s 1 c v nh s 0 trn mn hnh. u(1) = 0.
i 1 2 n ; i = k+1..n - Nhng ngi cn li (mang m s k+1..n) G n ln v ch.
1 2 - Ngi s 1 ghi s 1 ln mn hnh (c ch), MH = u(1)+1 = 0 + 1 = 1.
1 1 2 n-1 - Ngi s 1 G nt n-1 ln c ch, MH = n.
i 1 2 n ; i = 2..k - Nhng ngi s 2..k G n ln c ch, MH = n+(k-1).n = k.n = m.
Trng hp 2: r = 0 v k > 0. Ta c m = k.n+r, 0 < r < n, k > 0. Trng hp ny cn n-1 ngi thc
hin cc thao tc v ch, 1 ngi thc hin r cp thao tc G c ch v cng chnh ngi phi thc hin
(n-r) cp thao tc v ch. Ta s dng 2 ngi , s 1 v s 2 nh sau.
1 1 - Ngi s 1 c v nh s 0. u(1) = 0.
i 1 2 n ; i = k+2..n - Nhng ngi m s t k+2 n n G n ln v ch.
1 2 - Ngi s 1 Ghi 1 ln MH. MH = u(1)+1 = 0 + 1 = 1.
2 1 - Ngi s 2 c v nh s 1. u(2) = 1.
1 1 2 n-r - Ngi s 1 G n-r ln v ch.
Tip n l nhng thao tc c ch:
2 2 - Ngi s 2 Ghi s 2 ln MH, MH = u(2)+1 = 1 + 1 = 2.
1 1 2 r-1 - Ngi s 1 G nt r-1 ln c ch, MH = 2+(r-1).
2 1 2 n-1 - Ngi s 2 G nt n-1 ln c ch, MH = 2+(r-1)+(n-1) = n+r.
i 1 2 n ; i = 3..k+1 - Nhng ngi s 3..k+1 G n ln c ch, MH = n+r+(k-1).n = k.n+r.
Trng hp 3: r = 0 v k = 0, do m = r > 2. Trng hp ny cn n-1 ngi thc hin cc thao tc
v ch, 1 ngi thc hin r cp thao tc G c ch v cng chnh ngi phi thc hin (n-r) cp thao tc
v ch. Ta s dng 2 ngi , s 1 v s 2 nh sau.
1 1 - Ngi s 1 c v nh s 0 trn MH. u(1) = 0.
i 1 2 n ; i = 3..n - Nhng ngi t s 3 n n G n ln v ch.
2 1 2 n-1 - Ngi s 2 G n-1 ln v ch.
1 2 - Ngi s 1 Ghi s 1 ln MH. MH = u(1)+1 = 0+1 = 1.
2 1 - Ngi s 2 c s 1 trn MH. u(2) = 1.
1 1 2 n-r+1 - Ngi s 1 G n-r+1 ln v ch.
2 2 - Ngi s 2 Ghi s 2 ln MH. MH = u(2)+1 = 1+1 = 2.
1 1 2 r-2 - Ngi s 1 G r-2 ln c ch, MH = 2 + (r-2) = r.
Phn di y trnh by cu trc d liu v cc th tc c v xp lch. Hai th tc ph tr Lenh2
v Lenh4 dng ghi mt lnh 2 tham bin dng i t v lnh 4 tham bin dng i t
1
t
2
k vo output file g
KH.OUT. Trong cc ch thch di y d[i] l s trong u nh KH th i, t[i] l s thao tc G nh KH i
thc hin, MH mn hnh, k hiu MH = x cho bit ta khng quan tm n gi tr ca MH v sm mun
gi tr ny s b xa.
uses crt;
const

147
fn = 'kh.inp'; gn = 'kh.out';
bl = #32; nl = #13#10; mn = 100;
{ bl du cch; nl xung dng }
type
mi1 = array[0..mn+1] of integer;
var
f,g: text;
n, m, mh: integer;
d,t: mi1;
{ mh Mn hnh }
d[i] - so nho trong dau,
t[i] - con dem lenh cua nguoi i }
procedure Doc;
begin
assign(f,fn); reset(f);
read(f,n,m); close(f);
end;
procedure Lenh2(i,tt: integer);
begin writeln(g,i,bl,tt); end;
procedure Lenh4(i,tt1,tt2,k: integer);
begin if k > 0 then writeln(g,i,bl,tt1,bl,tt2,bl,k); end;
procedure XepLich;
var k,r,i: integer;
begin
assign(g,gn); rewrite(g);
if (n < 2) or (m < 2) or (m > n*n) then
begin writeln(g,0); close(g); exit; end;
k := m div n; { k nguoi co ich }
r := m mod n; { va r thao tac co ich }
if (r = 0) then
begin
Lenh2(1,1); {MH=0,d[1]=0,t[1]=1}
for i := k+1 to n do Lenh4(i,1,2,n);
{MH=x,t[i]=2n,i=k+1..n}
Lenh2(1,2); {MH=1}
Lenh4(1,1,2,n-1); {MH=n,t[1]=2n}
for i := 2 to k do Lenh4(i,1,2,n);
{ MH =n+(k-1)n=kn=m,t[i]=2n,i=2..k}
close(g); exit;
end;
{ r > 0 }
if k > 0 then
begin { r,k > 0 }
Lenh2(1,1); {MH=0,d[1]=0,t[1]=1}
{ Bo nhung nguoi vo ich }
for i:=k+2 to n do Lenh4(i,1,2,n);
{MH=x,t[i]=2n,i=k+2..n}
Lenh2(1,2); {1 Ghi;MH=1,t[1]=2}
Lenh2(2,1); {2 Doc;MH=1;d[2]=1,t[2]=1}
{ Cac thao tac vo ich cua 1 }
Lenh4(1,1,2,n-r); {MH=x,t[1]=2+2(n-r)=2(n-r+1)}
{ Tu day la cac thao tac co ich }
Lenh2(2,2); {MH=2,t[2]=2}
Lenh4(1,1,2,r-1);
{MH=2+r-1,t[1]=2(n-r+1)+2(r-1)=2n}
Lenh4(2,1,2,n-1);{MH=2+r-1+n-1=n+r,t[2]=2n}
for i := 3 to k+1 do Lenh4(i,1,2,n);

148
{MH=n+r+(k-1)n=kn+r=m,t[i]=2n,i=3..k+1}
close(g); exit;
end;
{ k = 0, r > 0 }
Lenh2(1,1); {1 Doc,d[1]=0,t[1]=1}
{ Bo nhung nguoi vo ich }
for i:=3 to n do Lenh4(i,1,2,n);{MH=x,t[i]=2n,i=3..n}
{ n-1 thao tac vo ich cua 2 }
Lenh4(2,1,2,n-1);{MH=x,t[2]=2(n-1)}
Lenh2(1,2); {1 Ghi,MH=1,t[1]=2}
Lenh2(2,1); {2 Doc,MH=1,d[2]=1,t[2]=2n-2+1=2n-1}
{ Cac thao tac vo ich cua 1 }
Lenh4(1,1,2,n-r+1);{MH=x,t[1]=2+2(n-r+1)=2(n-r+2)}
Lenh2(2,2); {MH=2,t[2]=2n}
Lenh4(1,1,2,r-2);{MH=2+r-2=r=m,t[1]=2(n-r+2)+2(r-2)=2n}
close(g);
end;
Bn c th vit thm th tc test kim tra xem lch xp v ghi trong tp KH.OUT c tha cc
yu cu ca u bi hay khng. Th tc s dng cc mng sau y. Mng d[1..n], d[i] l s nh trong u
ngi s i. Mng t[1..n], t[i] l s ln ngi th i thc hin cc thao tc c (1), Ghi (2). Do thao tc c
phi thc hin trc v hai thao tc c - Ghi phi an xen nn thi im st trc thao tc c ca ngi
th i ta phi c t[i] l s chn v thi im st trc thao tc Ghi phi c t[i] l s l. Mi ln c 1 dng
lnh th tc phi xt xem dng lnh cha 2 hoc 4 s. Th tc phi thc hin cc kim tra sau y.
Kim tra lnh dng i v: 1 s i s n, v = 1 hoc 2. Nu v = 1 th t[i] phi l s chn, nu v = 2 th t[i]
phi l.
Kim tra lnh dng i v1 v2 k: tng t nh trn.
Thc hin lnh i v: Nu v = 1 (thao tc c) th gn d[i] := MH; ngc li, nu v = 2 (ghi) th gn
MH := d[i] + 1. Trong c hai trng hp u tng con m lnh t[i] thm 1 n v.
Sau khi c xong tp KH.OUT phi duyt li cc con m m bo rng d[i] = 2.n vi mi i =
1..n. Cui cng kim tra xem MH = m?

procedure DocLenh(var i,t1,t2,k,v: integer);
begin
read(g,i,t1); v := 2;
if seekeoln(g) then exit;
readln(g,t2,k); v := 4;
end;
procedure XemLenh(i,t1,t2,k,KieuLenh: integer);
begin
if KieuLenh = 2 then writeln(i,bl,t1)
else writeln(i,bl,t1,bl,t2,bl,k);
end;
function Lenh(i,c: integer): Boolean;
begin
Lenh := false;
if (i < 1) or (i > n) then exit;
case c of
1: begin
if odd(t[i]) then exit;
inc(t[i]); d[i] := mh;
end;
2: begin
if not(odd(t[i])) then exit;
inc(t[i]); mh := d[i]+1;
end;

149
else exit;
end;
Lenh := true;
end;
function KiemTraLenh(i,t1,t2,k,v: integer): Boolean;
var j: integer;
begin
if v = 2 then KiemTraLenh := Lenh(i,t1)
else
begin
KiemTraLenh := false;
for j := 1 to k do
begin
if not Lenh(i,t1) then exit;
if not Lenh(i,t2) then exit;
end;
KiemTraLenh := true;
end;
end;
procedure Test;
var i,t1,t2,k,v,n2: integer;
begin
mh := 0;
fillchar(d,sizeof(d),0);
fillchar(t,sizeof(t),0);
assign(g,gn); reset(g);
while not Seekeof(g) do
begin
DocLenh(i,t1,t2,k,v);
XemLenh(i,t1,t2,k,v);
if not KiemTraLenh(i,t1,t2,k,v) then
begin
writeln('Sai '); close(g);
exit;
end;
end;
n2 := n+n;
for i:=1 to n do
if (t[i] <> n2) then
begin
writeln('Sai '); close(g);
exit;
end;
if (mh <> m) then
begin
writeln('Sai '); close(g);
exit;
end;
writeln('Dung');
close(g);
end;
Chng trnh C#
// C#
using System;

150
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace SangTao2 {
class KhoaHoc {
const string fn = "KH.INP";
const string gn = "KH.OUT";
const int MN = 1002;
static int[] d = new int[MN]; // So nho trong dau
static int[] t = new int[MN]; // con dem thao tac
static int n; // nha khoa hoc
static int m; // man hinh cuoi
static int mh;
static StreamWriter g;
static StreamReader f;

static void Main(string[] args){
Run();
}
static void Run() { // Kiem tra tren 1 file
Doc();
Console.WriteLine("n = " + n + " m = " + m);
XepLich();
Console.WriteLine("Output file " + gn);
Console.WriteLine(File.ReadAllText(gn));
Console.WriteLine("Now Testing...");
Test();
Console.ReadLine();
}
// Kiem tra file output KH.OUT
static void Test(){
f = File.OpenText(gn);
Array.Clear(d, 0, d.Length);
Array.Clear(t, 0, t.Length);
mh = 0;
int i, t1, t2, k, v;
while (DocLenh(out i, out t1, out t2, out k, out v)){
XemLenh(i, t1, t2, k, v);
if (!KiemTraLenh(i, t1, t2, k, v)){
Console.WriteLine("SAI LENH");
return;
}
}
f.Close();
for (int j = 1, nn = n + n; j <= n; ++j)
if (t[j] != nn){
Console.WriteLine("SAI SO THAO TAC" + t[j]);
return;
}
if (mh != m) Console.WriteLine("SAI KET QUA MH");
else Console.WriteLine(" LAP LICH DUNG "); }
static bool KTLenh2(int i, int tt){
switch (tt){
case 1: if (t[i] % 2 != 0) return false;
++t[i]; d[i] = mh; return true;
case 2: if (t[i] % 2 == 0) return false;

151
++t[i]; mh = d[i] + 1; return true;
default: return false;
}
}
static bool KiemTraLenh(int i, int t1, int t2,
int k, int v){
if (i < 1 || i > n) return false;
if (v == 2) return KTLenh2(i, t1);
for (int j = 1; j <= k; ++j){
if (!KTLenh2(i, t1)) return false;
if (!KTLenh2(i, t2)) return false;
}
return true;
}
static void XemLenh(int i, int t1, int t2, int k, int v)
{
if (v == 2) Console.WriteLine(i + " " + t1);
else Console.WriteLine(i+" "+t1+" "+t2+" "+k);
}
static bool DocLenh(out int i, out int t1,
out int t2, out int k, out int v){
i = t1 = t2 = k = v = 0;
if (f.EndOfStream) return false;
int[] c = Array.ConvertAll((f.ReadLine()).Split(
new char[] { '\t', ' ' },
StringSplitOptions.RemoveEmptyEntries),
new Converter<String, int>(int.Parse));
foreach (int x in c) ++v;
Console.Write(" v = " + v + ": ");
if (v != 2 && v != 4) return false;
i = c[0]; t1 = c[1];
if (v == 4) { t2 = c[2]; k = c[3]; }
return true;
}
static void Doc(){
int[] v =
Array.ConvertAll((File.ReadAllText(fn)).Split(
new char[] { '\0', '\n', '\t', '\r', ' ' },
StringSplitOptions.RemoveEmptyEntries),
new Converter<String, int>(int.Parse));
n = v[0]; // n nha khoa hoc
m = v[1]; // Gia tri man hinh
}
static void XepLich(){
g = File.CreateText(gn);
if (n < 2 || m < 2 || m > n * n){
g.WriteLine("0");
g.Close();
return;
}
int k = m / n;
int r = m % n;
Console.WriteLine("k = " + k + " r = " + r);
if (r == 0){
Lenh2(1, 1);
for (int i = k + 1; i <= n; ++i)
Lenh4(i, 1, 2, n);

152
Lenh2(1, 2);
Lenh4(1, 1, 2, n - 1);
for (int i = 2; i <= k; ++i) Lenh4(i, 1, 2, n);
g.Close();
return;
}
if (k > 0){
Lenh2(1, 1); // 1 Doc
// Bo nhung nguoi vo ich
for (int i = k + 2; i <= n; ++i)
Lenh4(i, 1, 2, n);
Lenh2(1, 2); // 1 Ghi
Lenh2(2, 1); // 2 Doc
Lenh4(1,1,2,n-r);//cac thao tac vo ich cua 1
// Tu day la cac thao tac co ich
Lenh2(2, 2); // 2 Ghi
Lenh4(1, 1, 2, r - 1); // 1 DG r-1 lan
Lenh4(2, 1, 2, n - 1); // 2 DG n-1 lan
for (int i = 3, k1 = k + 1; i <= k1; ++i)
Lenh4(i, 1, 2, n);
g.Close();
return;
}
// k = 0
Lenh2(1, 1); // 1 Doc. Tu 3..n vo ich
for (int i = 3; i <= n; ++i) Lenh4(i, 1, 2, n);
Lenh4(2, 1, 2, n - 1);
Lenh2(1, 2); // 1 Ghi
Lenh2(2, 1); // 2 Doc
Lenh4(1,1,2,n-r+1); // Cac thao tac vo ich cua 1
Lenh2(2, 2); // 2 Ghi co ich
Lenh4(1, 1, 2, r - 2); // 1 Ghi not co ich
g.Close();
}
static void Lenh2(int i, int t)
{ g.WriteLine(i + " " + t); }
static void Lenh4(int i, int t1, int t2, int k) {
if (k > 0)
g.WriteLine(i + " " + t1 + " " + t2 + " " + k);
}
} // KhoaHoc
} // SangTao2
phc tp
Thut ton pht sinh v ghi vo file kt qu ti a 2.n
2
dng lnh.
4.9 Chn chic ng h
Olimpic Quc t
C 9 chic ng h in t treo trn mt bng theo s 3 3. Cc ng h c m s t 1 n 9
theo trt t t tri qua phi, t hng trn xung hng di. Mi ng h c 4 im ch gi ng vi cc gi
12, 3, 6 v 9. Gi hin tr ca mi ng h ng vi im sng ^. iu khin cc ng h ngi ta s
dng 9 phm vi cc chc nng c m t nh trong hnh v. Khi nhn vo mt phm th c 4 ng h
ng lot nhy im sng i 90
o
theo chiu kim ng h cng thm 3 gi tnh t gi hin tr. Th d, khi
nhn phm 1 th 4 ng h 1, 2, 4 v 5 s c chnh gi theo lut trn. Bit gi hin ti ca cc ng h.
Hy xc nh mt dy ngn nht cc phm cn nhn cc ng h ng lot tr 12 gi.

153



+

+

+
S b tr
9 ng h
^

+

+

+

^

+


+

^

+

C C C

C 9h C 6h C 9h C C

+

^

+

C

^

+

+

+

+

^


+

+

+

C 9h C 12h 3h

^

+

+

+

+

+

+

+

+
9 phm
iu khin
+

^

^

C 12h 6h 6h 1 2 3
4 5 6
9 ng h, ^ gi ang tr
7 8 9

D liu vo: tp vn bn DONGHO.INP gm 12 dng
3 dng u tin gm 9 s tr gi ti thi im u b tr theo ma trn 3 3.
Dng th i trong s 9 dng tip theo, i = 1, 2, 3, 4 ghi 4 s t nhin th hin m s ca 4 ng h s
nhy im sng 90
o
khi ta nhn phm i.
Cc s trn cng dng cch nhau qua du cch.
D liu ra: Tp vn bn DONGHO.OUT gm hai thng tin:
- Bi ton c nghim (ghi s 1) hoc v nghim (ghi s 0).
- Dy phm ngn nht cn nhn cho trng hp c nghim.

DONGHO.INP DONGHO.OUT
9 6 9
9 12 3
12 6 6
1 2 4 5
2 3 5 6
4 5 7 8
5 6 8 9
1 2 3 5
1 4 5 7
3 5 6 9
5 7 8 9
1
1 2 4 4



154
2 5 6 8
ngha: Nhn ln lt cc phm 1, 2, 4,
4
c 9 ng h u ng lot tr 12 gi.

Thut ton
Ta nhn thy rng do cc ng h hot ng c lp vi nhau nn dy phm cn nhn l giao hon,
ngha l c th lit k dy phm theo trt t ty . Th d, nhn cc phm 1, 2, 3 s mang li kt qu nh
khi nhn dy phm 2, 1, 3 hoc theo bt k hon v no ca 3 phm . Ngoi ra, nu mt phm c nhn
n mt bi ln ca 4 th im sng tr gi s quay li ng v tr ban u, do ta khng di g m nhn
mt phm qa 3 ln. T hai nhn xt trn ta thy rng c th dng k thut vt cn, c th l xt cc t hp
dy phm p[1..9], p[i] = 0..3 biu th s ln bm phm i. Vi mi t hp p ta tnh xem cc ng h c cp
nht ra sao. Nu c 9 ng h u nhy v thi im 12 gi th ta chn phng n c s ln bm phm t
nht trong s cc t hp ng vin.
Di y l mt vi chi tit s dng trong
chng trnh. Ta khi to sn mng hai chiu m t
chc nng ca cc phm iu khin, phim[i,j] cho
bit khi nhn phm i th ng h j s c chnh.
var
phim: array[1..9,1..4] of
integer;
Sau khi c d liu ng vi th d c th th
mng phim s c gn tr nh sau:
phim = ((1,2,4,5),
(2,3,5,6),
(4,5,7,8),
(5,6,8,9),
(1,2,3,5),
(1,4,5,7),
(3,5,6,9),
(5,7,8,9),
(2,5,6,8));
Bn cng nn m t sn mt kiu mng 9 phn
t biu th cc phm v cc ng h.
type mi1 = array[1..9] of
integer;
var
dongHo: mi1;
f: text;
imin, imax: longint;
Bn c th s dng 9 vng for lng nhau ng
vi 9 phm, mi vng bin thin t 0 n 3 ng vi s
ln nhn phm.
Bin ts dng tnh tng s ln nhn phm. D
thy, mi phm c nhn ti a 3 ln, vy 9 phm s
c nhn ti a 9.3 = 27 ln. Ta ly 28 lm ga tr
khi u cho vic tnh tsmin - tng s ln nhn phm t nht. Ta cng nn chuyn cc s trn mt ng h
l (12,3,6,9) sang cc s h 4 l (0,1,2,3) cho tin tnh ton. Hm Sum(p) tnh tng 9 phn t ca mng p
- chnh l tng s ln nhn phm ca phng n p. Hm KiemTra(q) thc hin vic kim tra xem 9 ng
h c cng tr n 12h hay khng, q[i] l s ln ng h i c cp nht khi thc hin phng n p.

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

1 2 3

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

4 5 6

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

7 8 9

Chc nng ca cc phm iu khin

155
Bn cng c th s dng h 4 x l nh sau: Cc phng n nhn 9 phm bin thin t
(0,0,0,0,0,0,0,0,0) n (3,3,3,3,3,3,3,3,3) ng vi imin = 0 v imax = 4
9
-1 = 2
18
-1 = (1 shl 18) - 1 =
262143. Ta cho i bin thin t imin n imax. Vi mi i ta xy dng phng n nhn phm bng cch gi
th tc Split(i,p) chuyn s i sang dng biu din h 4 ghi vo mng p, trong p[j] s l s ln nhn
phm j. Bit p ta d dng cp nht cc ng h.
Chng trnh di y ci t 2 phng n vt cn, Run1 chn vng for lng nhau v Run2 - tnh
ton theo h 4.
(* Pascal *)
(* Dong ho *)
const bl = #32; fn = 'DONGHO.INP'; gn = 'DONGHO.OUT';
type mi1 = array[1..9] of integer;
var
dongHo,kq: mi1;
f,g: text;
imin, imax: longint;
s, tsmin: integer;
var
phim: array[1..9,1..4] of integer;
procedure Split(x: longint; var a: mi1);
var i: integer;
begin
for i := 1 to 9 do
begin
a[i] := x mod 4;
x := x div 4;
end;
end;
procedure Doc;
var i,j: integer;
begin
assign(f,fn); reset(f);
for i:=1 to 9 do read(f,dongHo[i]);
for i:=1 to 9 do
for j:=1 to 4 do read(f,phim[i,j]);
close(f);
end;
procedure Ghi;
var i,j: integer;
begin
assign(g,gn); rewrite(g);
if tsmin = 28 then writeln(g,0) { vo nghiem }
else
begin { co nghem }
writeln(g,1);
for i := 1 to 9 do
for j := 1 to c[i] do write(g,i,bl);
writeln(g);
end;
close(g);
end;
procedure Init;
var i: integer;
begin
for i:=1 to 9 do dongHo[i] := (dongHo[i] div 3) mod 4;
imin := 0;

156
imax := 1;
imax := (imax shl 18 - 1);
end;
function KiemTra(var q: mi1): Boolean;
var i: integer;
begin
KiemTra := false;
for i:=1 to 9 do
if (dongHo[i]+q[i]) mod 4 <> 0 then exit;
KiemTra := true;
end;
function Sum(var q: mi1): integer;
var i,s: integer;
begin
s := 0;
for i:=1 to 9 do s := s+q[i];
Sum := s;
end;
procedure XuLiFor;
var j,k,ts: integer;
q,p: mi1; { p[i] so lan nhan phim i }
i,ikq: longint;
begin
tsmin := 28; { = 3*9+1 }
for p[1] := 0 to 3 do
for p[2] := 0 to 3 do
for p[3] := 0 to 3 do
for p[4] := 0 to 3 do
for p[5] := 0 to 3 do
for p[6] := 0 to 3 do
for p[7] := 0 to 3 do
for p[8] := 0 to 3 do
for p[9] := 0 to 3 do
begin
fillchar(q,sizeof(q),0);
for j := 1 to 9 do
begin
for k := 1 to 4 do
inc(q[phim[j,k]],p[j]);
end;
if KiemTra(q) then
begin
ts := Sum(p);
if ts < tsmin then
begin
tsmin := ts;
kq := p;
end;
end;
end;
end;
procedure XuLi;
var j,k,ts: integer;
q,p: mi1;
i,ikq: longint;
begin
tsmin := 28; { = 3*9+1 }

157
for i:=imin to imax do
begin
Split(i,p); { bam phim j p[j] lan }
fillchar(q,sizeof(q),0);
for j := 1 to 9 do
begin
for k := 1 to 4 do
inc(q[phim[j,k]],p[j]);
end;
if KiemTra(q) then
begin
ts := Sum(p);
if ts < tsmin then
begin
tsmin := ts;
ikq := i;
end;
end;
end;
Split(ikq,kq);
end;
procedure Run1;
begin
Doc; Init;
XuLiFor; Ghi;
end;
procedure Run2;
begin
Doc; Init;
XuLi; Ghi;
end;
BEGIN
Run1;
END.
Chng trnh C#
// C#
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace SangTao2 {
class DongHo {
const string fn = "DONGHO.INP";
const string gn = "DONGHO.OUT";
const int cc = 9;
static int[,] phim = new int [9,4];
static int[] dongHo = new int[cc];
static int [] kq = new int [cc];
static int smin = 0; // Tong so lan nhan phim
static void Main(string[] args) {
Run2();
Console.ReadLine();
}
static void Run1(){

158
Doc(); Init(); XuLi(); Ghi(); XemKq();
}
static void Run2(){
Doc(); Init();
XuLiFor(); Ghi(); XemKq();
}
static void XuLiFor(){
int [] p = new int [cc];// 9 phim
int[] dh = new int[cc];//so lan nhay kim cua 9 DH
int s = 0;
smin = 28;
for (p[0]=0; p[0] < 4; ++p[0])
for (p[1]=0; p[1] < 4; ++p[1])
for (p[2]=0; p[2] < 4; ++p[2])
for (p[3]=0; p[3] < 4; ++p[3])
for (p[4]=0; p[4] < 4; ++p[4])
for (p[5]=0; p[5] < 4; ++p[5])
for (p[6]=0; p[6] < 4; ++p[6])
for (p[7]=0; p[7] < 4; ++p[7])
for (p[8]=0; p[8] < 4; ++p[8]){
Array.Clear(dh,0,dh.Length);
for (int j = 0; j < cc; ++j)
//phim j nhan p[j] lan
for (int k = 0; k < 4; ++k)
// 4 DH chuyen kim
dh[phim[j, k]] += p[j];
if (KiemTra(dh)){
s = Sum(p);
if (s < smin){
smin = s;
p.CopyTo(kq,0);
}
}
}
}
static int Sum(int []p){ // Tong so lan nhan phim
int s = 0;
for (int i = 0; i < cc; ++i) s += p[i];
return s;
}
static void Doc() { // Doc du lieu tu input file
int[] v =
Array.ConvertAll((File.ReadAllText(fn)).Split(
new char[] { '\0', '\n', '\t', '\r', ' ' },
StringSplitOptions.RemoveEmptyEntries),
new Converter<String, int>(int.Parse));
int k = 0;
for (int j = 0; j < cc; ++j) dongHo[j] = v[k++];
for (int i = 0; i < cc; ++i)
for (int j = 0; j < 4; ++j)
phim[i, j] = v[k++];
}
static void Init() { // Khoi tri
for (int j = 0; j < cc; ++j)
dongHo[j] = (dongHo[j] / 3) % 4;
for (int i = 0; i < cc; ++i)
for (int k = 0; k < 4; ++k)

159
--phim[i, k];
}
static void XuLi(){
int imax = ((int)1 << 18) - 1;
int[] p = new int[cc]; smin = 28;
int[] q = new int[cc];
for (int i = 0; i <= imax; ++i){
int s = Split(i, p);
Array.Clear(q, 0, q.Length);
for (int j = 0; j < cc; ++j)
for (int k = 0; k < 4; ++k)
q[phim[j, k]] += p[j];
if (KiemTra(q))
if (s < smin){ smin = s; p.CopyTo(kq,0); }
}
}
static void Ghi(){
StreamWriter g = File.CreateText(gn);
if (smin < 28) { // co nghiem
g.WriteLine(1);
for (int i = 0; i < cc; ++i)
for (int j = 1; j <= c[i]; ++j)
g.Write((i + 1) + " ");
}
else g.WriteLine(0); // vo nghiem
g.Close();
}
static bool KiemTra(int[] q)// Kiem tra ca 9 DH tro ve 0?
{
for (int i = 0; i < cc; ++i)
if ((dongHo[i] + q[i]) % 4 > 0) return false;
return true;
}
// Tach x thanh cac chu so he 4 va tinh tong
static int Split(int x, int[] p){
int s = 0;
for (int i = 0; i < cc; ++i)
{ p[i] = x % 4; s += p[i]; x /= 4; }
return s;
}
static void XemKq(){
Console.WriteLine("\n Input file " + fn);
Console.WriteLine(File.ReadAllText(fn));
Console.WriteLine("\n Output file " + gn);
Console.WriteLine(File.ReadAllText(gn));
}
} // DongHo
} // SangTao2

4.10 S duy nht
Olimpic Baltics
Tp vn bn UNIQUE.INP cha dy s, mi s chim mt dng di khng qu 20 ch s. Trong
dy ny c duy nht mt s xut hin ng mt ln, cc s cn li u xut hin ng k ln. Hy tm s duy
nht . S k khng cho trc, nhng bit rng l mt s chn khc 0. Kt qu hin th trn mn hnh.

160

Thut ton
Ta da vo mt kin thc c t hng ngn nm trc, l biu din s theo v tr. Ta ln lt c
tng dng vo mt bin string sau ghi vo mt mng a s ln xut hin ca tng ch s ti tng v tr,
a[c,i] cho bit s ln xut hin ca ch s c ti ct i tnh t tri qua phi.
Vi th d cho, trn ct 1 ta tnh c a[1,1] = 5, a[2,1] = 4, a[3,1] = 0,... , a[8,1] = 4...
Nh vy mng a c kch thc 10 hng cha 10 ch s 0..9 v 20 ct cha cc ch s di nht.
Sau khi c xong d liu, ta thy mi phn t ca mng a hoc l chia ht cho k do l s chn, hoc l
s l c dng m.k + 1, m = 0, 1, 2,... Nu a[c,i] l s l th c s l ch s xut hin ti ct i ca s duy nht
cn tm.
Chng trnh Pascal
(* Pascal *)
procedure XuLi;
const mn = 20;
ChuSo = ['0'..'9'];
fn = 'unique.inp';
var a: array['0'..'9',1..mn] of integer;
f: text;
i: integer;
s: string;
cs: char;
begin
fillchar(a,sizeof(a),0);
assign(f,fn); reset(f);
while not seekeof(f) do
begin
readln(f,s);
for i:=1 to length(s) do
if s[i] in ChuSo then inc(a[s[i],i]);
end;
close(f);
s := ''; { Ket qua }
for i := 1 to mn do
for cs := '0' to '9' do
if Odd(a[cs,i]) then s := s+cs;
writeln(s);
end;
BEGIN
XuLi;
readln;
END.
Chng trnh C#
// C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

UNIQUE.IN
P
MN HNH
1357
2008
80
1357
2008
80
2008
1357
10203040
80
2008
80
1357

10203040

Gii thch: S duy nht cn tm
l 10203040. Cc s cn li
u xut hin 4 ln.

161
namespace SangTao2 {
class Unique {
const string fn = "UNIQUE.INP";
static void Main(string[] args){
Console.WriteLine(XuLi());
Console.ReadLine();
}
static string XuLi(){
string s;
StreamReader f = File.OpenText(fn);
int mn = 20;
int [,] a = new int[10,mn];
Array.Clear(a, 0, a.Length);
while (true){
s = f.ReadLine().Trim();
if (s.Length == 0) break;
for (int i = 0; i < s.Length;++i)
if (s[i] >= '0' && s[i] <= '9')
++a[s[i]-'0',i];
}
f.Close();
string kq = "";
for (int i = 0; i < mn; ++i)
for (int cs = 0; cs <= 9; ++cs)
if (a[cs, i] % 2 == 1)
kq += cs;
return kq;
}
} // Unique
} // SangTao2
phc tp
Nu c n s di ti a m ch s th ta cn xt mi ch s 1 ln, ngha l tng cng cn n.m thao tc.
Duyt mng a cn 10.m thao tc l s rt nh so vi n.m.
Cc bin th ca bi UNIQUE
1. Nu u bi cho bit s k th khng cn i hi k l s chn.
2. Bit duy nht mt s xut hin ng m ln, cc s cn li u xut hin k ln nh nhau, k = m v
k v m nguyn t cng nhau. Bn th suy ngh xem c cn bit c th cc gi tr ca m v k khng? Bn
th tm mt s iu kin ca k v m?
3. Thay cc s bng cc dy k t A..Z di ti a m.
________________________

21.01.2010
NXH

You might also like