Professional Documents
Culture Documents
SNG TO
TRONG THUT TON
V
LP TRNH
vi ngn ng Pascal v C#
Tp 1
MC LC
Chng I
Bi 1.1.
Li ni u
1
2
Bi 1.2.
S cp cng
Bi 1.3.
S cp nhn
11
Bi 1.4.
13
Bi 1.5.
16
Bi 1.6.
21
Chng II
Bi 2.1.
SINH D LIU VO V RA
Sinh ngu nhin theo khong
27
27
Bi 2.2.
29
Bi 2.3.
31
Bi 2.4.
33
Bi 2.5.
36
Bi 2.6.
40
Bi 2.7.
42
Bi 2.8.
43
Bi 2.9.
S cao h
46
Bi 2.10.
Tp cc hon v
49
Bi 2.11.
53
Bi 2.12.
56
Bi 2.13.
60
Bi 2.14.
m tu
62
Bi 2.15.
Sp on
65
Chng III
Bi 3.1.
BN PHM V MN HNH
Bng m ASCII
79
79
Bi 3.2.
B T l kh
80
Bi 3.3.
Hm GetKey
88
Bi 3.4.
Tr chi 15
90
Bi 3.5.
Bng nhy
95
Chng IV
Bi 4.1.
T CHC D LIU
Cm
107
107
Bi 4.2.
Bi gp
112
Bi 4.3.
Chui ht
120
Bi 4.4.
Sp mng ri ghi tp
129
Bi 4.5.
abc - sp theo ch dn
133
Bi 4.6.
Xu mu
141
Chng V
Bi 5.1.
153
153
Bi 5.2.
Xp vic
158
Bi 5.3.
Xp ba l
165
Bi 5.4.
170
Bi 5.5.
Trn hai tp
177
Chng VI
Bi 6.1.
193
195
Bi 6.2.
T chun
207
Bi 6.3.
Tm ng trong m cung
216
Chng VII
Bi 7.1.
Bi 7. 2.
Bi 7.3.
Bi 7.4.
QUY HOCH NG
Chia thng
Palindrome
Cm hoa
Tm cc ng ngn nht
227
228
235
243
253
Chng VIII
Bi 8.1.
Bi 8.2.
Bi 8.3.
Bi 8.4.
Bi 8.5.
Bi 8.6.
Bi 8.7.
Bi 8.8.
Bi 8.9.
SUY NGM
Lt nn
Ch s cui khc 0
Hnh ch nht ti i trong ma trn 0/1
Ma phng
Thp H Ni c
Thp H Ni xui
Thp H Ni ngc
Thp H Ni thng
Thp H Ni sc mu (H Ni Cu vng)
267
267
276
281
291
308
311
316
321
325
Li ni u
Th theo yu cu ca ng o bn c, chng ti bin son li cun Sng
to trong Thut ton v Lp trnh vi cc bi Ton Tin nng cao cho hc sinh
v sinh vin nhm cung cp nhng k thut lp trnh c bn gii nhng bi
ton kh trn my tnh.
Mt bi ton tin c hiu l kh nu ta s dng thut gii mi ny sinh
trong u khi va bit ni dung bi ton th hoc l ta thu c kt qu sai
hoc l li gii thu c s khng hu hiu theo ngha chng trnh i hi
qu nhiu b nh hoc/v chy qu lu. Nhng thut gii ny sinh lp tc
trong u nh vy thng c gi l thut gii t nhin. D nhin, khi nim
ny ch l tng i. Nu bn nm vng nhiu dng thut gii v tng
th sc vi nhiu bi ton kh th n mt lc no cc thut gii t nhin
ca bn s ng tin cy. cng chnh l mc ch ca s hc tp v rn luyn
v cng l c m ca ngi vit tp sch ny.
c sch khng i hi bn phi c tri thc g c bit. tip thu tt
v ng gp cho vic hiu chnh v ci tin ni dung cun sch ch cn bn bit
s dng mt trong cc ngn ng lp trnh: Pascal trong mi trng Turbo hoc
Free Pascal hoc C#.
Cc k thut lp trnh c minh ho qua nhng bi ton c th tng
ng vi trnh nng cao ca hc sinh v sinh vin. Hnh thc pht biu bi
ton suy cho cng l khng quan trng. Cc k thut lp trnh v phng php
xy dng thut gii cho nhng bi ton thng c dng rng ri trong qu
trnh thit k v ci t cc phn mm ng dng trong thc tin, cho nn vic
sm lm ch cc tri thc ny mi tht s l cn thit. Chnh v vy m chng
ti cho rng ni dung cun sch c th ph hp vi cc bn hc sinh, sinh vin
cc trng i hc v nhng bn c mun t hon thin tri thc trong lnh
vc gii thut v lp trnh. Thit ngh cun sch cng c th c dng lm ti
liu tham kho dy cc lp chuyn tin ca cc trng ph thng. Ni dung
sch gm hai phn. Phn th nht gii thiu vn tt v bn cht cc phng
php v k thut lp trnh v cc ton cc bn th sc. Phn th hai trnh
by v phn tch chi tit li gii cng vi nhng bnh lun v xut x ca cc
bi ton.
Trong tp sch ny cng cung cp ton vn cc chng trnh vit bng
ngn ng lp trnh Pascal v C# bn c tin so snh vi li gii ca mnh.
C hai phn u cp n ni dung ca tm chng nh sau.
Chng th nht trnh by s chung gii mt bi ton tin. Cc bi
tp chng ny hu ht thuc loi d gii. Chng th hai gii thiu cc k
thut sinh d liu mt cch t ng nhm phc v cho vic kim th (test)
chng trnh. Chng th ba trnh by cc k thut qun l bn phm v mn
hnh. Chng th t cp n cch thc t chc d liu cho mt bi ton tin.
Ba chng tip theo gii thiu ba trong s cc phng php kh ph bin
thng c vn dng trong thit k thut gii. l phng php tham lam,
phng php quay lui v quy hoch ng. Cc phng php ny u l khng
vn nng theo ngha khng th dng chng gii mi bi ton tin. Trong thc
CHNG 1
Hiu u bi
Ta k hiu (a, b) l c chung ln nht (ucln) ca hai s t nhin a v b. Hai s t
nhin a v b c gi l nguyn t cng nhau khi v ch khi (a, b) = 1. Khi ,
chng hn:
a. (23, 32) = 1, vy 23 l mt s cn tm. Theo tnh cht i xng, ta c ngay 32
cng l mt s cn tm.
b. (12, 21) = 3, vy 12 v ng thi 21 khng phi l nhng s cn tm.
c t: Gi hai ch s ca s t nhin cn tm x l a v b, ta c:
(1)
x = ab.
(2)
a, b = 0..9 (a v b bin thin trong khong 0..9).
(3)
a > 0 v x l s c hai ch s.
(4)
(ab, ba) = 1.
Ta k hiu x' l s i xng ca s x theo ngha ca u bi, khi ta c c t nh
sau:
(5) x = 10..99 (x bin thin t 10 n 99, v x l s c hai ch s).
(6) (x, x') = 1.
Nu x = ab th x' = ba. Ta c th tnh gi tr ca x' theo cng thc:
x' = (ch s hng n v ca x) * 10 + (ch s hng chc ca x).
K hiu n(x) l ton t ly ch s hng n v ca s t nhin x v k hiu
Chc(x) l ton t ly ch s hng chc ca x, ta c:
x' = n(x)*10 + Chc(x).
Tng hp li ta c c t:
S cn tm x phi tho cc tnh cht sau:x = 10..99 (x nm trong khong t 10 n
99).
(7) x' = n(x)*10 + Chc(x).
(8) (x, x') = 1 (c chung ln nht ca x v x' bng 1).
c t trn c th hin qua ngn ng phng trnh ta Pascal nh sau:
(9) for x:=10 to 99 do
if ucln(x, n(x)*10+Chc(x))=1 then Ly(x);
trong , ucln(a,b)l hm cho c chung ln nht ca hai s t nhin a v b;
Ly(x) l ton t hin th x ln mn hnh hoc ghi x vo mt mng no vi mc
ch s dng li, nu cn.
Ta lm mn c t (10):
ucln(a, b): Thut ton Euclid l chia lin tip, thay s th nht bng d ca n
khi chia cho s th hai ri hon v hai s.
(*----------------------------------Tim uoc chung lon nhat cua hai so
a va b. Thuat toan Euclid
--------------------------------------*)
function Ucln(a,b: integer): integer;
var r: integer;
begin
while b > 0 do
begin
r:= a mod b; a:= b; b:= r;
end;
Ucln:= a;
end;
n(x) = (x mod 10): s d ca php chia nguyn x cho 10, th d:
n(19) = 19 mod 10 = 9.
Chc(x) = (x div 10): thng nguyn ca php chia x cho 10, th d:
Chc(19) = 19 div 10 = 1.
Ly(x): write(x) hoc np gi tr x vo mng s theo cc thao tc sau:
n := n + 1;
s[n] := x;
n m s phn t hin np trong mng s.
trn. Cui cng ton t y := y - 1 cng c thc hin ging nh trng hp trn
nhng khi lng tnh ton li nhiu hn.
(* Pascal *)
(*---------------------------------So than thien (xy,yx) = 1
----------------------------------*)
program SoThanThien;
{$B-}
uses Crt;
const MN = 90;
var s: array[1..MN] of integer;
function Ucln(a,b: integer): integer; t vit
function SoDao(x: integer): integer;
var y: integer;
begin
y := 0;
repeat
{ ghep chu so hang don cua x vao ben phai y }
y := 10*y + (x mod 10);
x := x div 10; { loai chu so hang don }
until (x = 0);
SoDao := y;
end;
(*-------------------------------------Tim cac so thoa dieu kien dau bai
ghi vao mang s.
Output: so luong cac so tim duoc
----------------------------------------*)
function Tim: integer;
var x,d: integer;
begin
d := 0; {So luong cac so can tim }
for x := 10 to 99 do
if Ucln(x,SoDao(x)) = 1 then
begin
d := d + 1; s[d]:= x;
end;
Tim := d;
end;
(*-----------------------------------Hien thi mang s[1..n] tren man hinh.
--------------------------------------*)
procedure Xem(n: integer);
var i: integer;
begin
writeln;
for i := 1 to n do write(s[i]:4);
writeln;
end;
BEGIN
n := Tim; Xem(n); writeln;
10
//
C#
using System;
namespace SangTao1
{
/***********************************
So Than Thien: (xy, yx) = 1
**********************************/
class SoThanThien
{
static int mn = 90;
static int [] s = new int[mn];
static void Main(string[] args)
{
Run();
Console.ReadLine();
}
static void Run()
{
int n = Find();
for (int i=0;i<n;++i)
Console.Write(s[i] + " ");
Console.WriteLine("\n Tong cong: "+n+" so");
}
static int Find()
{
int d = 0;
for (int x = 10; x < 100; ++x)
if (Ucln(x,SoDao(x))==1) s[d++] = x;
return d;
}
static int Ucln(int a, int {}b)
{
int r;
while (b != 0){ r = a%b;a = b;b = r; }
return a;
}
static int SoDao(int x)
{
int y = 0;
do { y = y*10+(x%10); x /= 10; } while (x!=0);
return y;
}
} // SoThanThien
} // SangTao1
Ci tin
Ta vn dng tnh i xng nhn xt phn trn ci tin chng trnh. Nh
vy ch cn kho st cc s x = ab, vi a > b 0. Trng hp a = b ta khng
xt v khi x' = x v do Ucln(x, x) = x 10 1.
Nu b = 0 ta c x = 10a v x' = a. Ta thy Ucln(10a, a) = a = 1 khi v ch
khi a = 1. Do ta xt ring trng hp ny. Khi ab = 10 ta c (10, 1) = 1.
Vy 10 chnh l mt s cn tm v l s u tin.
11
(* Pascal *)
(*------------------------------------So Than thien: Phuong an 2
---------------------------------------*)
function Tim2: integer;
var a,b,d: integer;
begin
d:= 1; {So luong cac so can tim}
s[d] := 10;
for a := 1 to 9 do
for b := 1 to a-1 do
if Ucln(a*10+b,b*10+a)=1 then
begin
d := d + 1; s[d] := a*10 + b;
d := d + 1; s[d] := b*10 + a;
end;
Tim2 := d;
end;
// C#
// Phuong an 2
static int Find2()
{ int a,b, d = 0;
s[d++] = 10;
for (a = 1; a <= 9; ++a)
for (b = 1; b < a; ++b)
if (Ucln(10*a + b, 10*b + a) == 1)
{ s[d++]=10*a+b; s[d++]=10*b+a; }
return d;
}
Bi 1.2. S cp cng
Tm cc s t nhin l c ba ch s. Ba ch s ny, theo trt t t tri qua phi
to thnh mt cp s cng.
c t
1. x l s t nhin c ba ch s: x = 100*a + 10*b + c.
2. x l s l nn ch s hng n v c phi l s l: c = 1, 3, 5, 7, 9.
3. Ch s hng trm ca x phi khc 0: a = 1..9.
4. Nu dy a, b, c lp thnh mt cp s cng th s ng gia b l trung bnh
cng ca hai s u v cui: b = (a + c)/2 hay 2b = a+c.
T (4) ta suy ra (a + c) l s chn. Do c l, (a + c) chn nn a l.
Nu bit a v c ta tnh c x = 100a +10(a + c) / 2 + c
= 100a + 5(a + c) + c = 105a + 6c.
V ch c 5 ch s l l 1, 3, 5, 7 v 9 nn t hp ca a v c s cho ta 25 s.
T chc d liu
12
Ch
Th tc inc(d) trong chng trnh TP di y tng gi tr ca bin d ln thm 1 n
v, tc l tng ng vi cu lnh d := d + 1 v ++d (C#). Tng t, th tc
dec(d) s gim gi tr ca bin d xung 1 n v, tng ng vi cu lnh d := d
1 v --d (C#).
Tng qut hn, ta c th vit:
inc(d,n) tng ng vi d := d + n v
dec(d,n) tng ng vi d := d n.
Khi n = 1 th c th b qua tham s th hai.
(*
Pascal
*)
13
//
C#
using System;
namespace SangTao1
{
class SoCapCong
{
static void Main(string[] args)
{
Show(Find());
Console.WriteLine("\n fini");
Console.ReadLine();
}
static int[] Find()
{
int d = 0;
int [] ChuSoLe = {1,3,5,7,9};
int []s = new int[25];
int x;
for (int i = 0; i < 5; ++i)
{
x = 105 * ChuSoLe[i];
for (int j = 0; j < 5; ++j)
s[d++] = x + 6 * ChuSoLe[j];
}
return s;
}
static void Show(int[] s)
{
foreach (int x in s)
Console.Write(x + " ");
}
} // SoCapCong
} // SangTao1
Ch thch
1. Trong C# mt hm c th cho ra gi tr l mt mng nh hm Find trong chng
trnh trn.
2. Lnh foreach (int x in a) P(x) thc hin thao tc P(x) trn mi phn
t x ca mng, t phn t u tin a[0] n phn t cui cng a[a.Length] vi
a.Length l chiu di (s phn t) ca mng a.
Ch
14
Bi 1.3. S cp nhn
Tm cc s t nhin c ba ch s. Ba ch s ny, theo trt t t tri qua phi
to thnh mt cp s nhn vi cng bi l mt s t nhin khc 0.
c t
Ch rng ta ch xt cc cp s trn dy s t nhin vi cng bi d l mt s
nguyn dng. Gi x l s cn tm, ta c:
1. x l s c ba ch s: x = 100*a + 10*b + c.
2. a = 1..9; b = a*d; 0 < c = a*d*d 9.
H thc 2 cho php ta tnh gii hn trn ca d:
ad 2 9
d 9/a
V d l s nguyn nn ta phi c d trunc(sqrt(9 div a)), trong
sqrt l hm tnh cn bc hai, trunc l hm ly phn nguyn.
Ta cho a bin thin trong khong 1..9 ri cho cng bi d bin thin trong khong t
1 n trunc(sqrt(9 div a)). Vi mi cp s a v d ta tnh
x = 100*a+10*a*d+a*d*d = a*(100+10*d+d*d)
Tuy nhin, ta c th nhm tnh trc cn trn ca d th s phi gi cc hm trunc v
sqrt l nhng hm thao tc trn s thc do s tn thi gian.
(*
Pascal
Cn trn d
*)
------------------------------*)
program CapNhan;
uses crt;
const MN = 30;
cd: array[1..9] = (3,2,1,1,1,1,1,1,1);
var s: array [1..MN] of integer;
n: integer;
function Tim: integer;
var a,d,n: integer;
begin
n:= 0;
for a:= 1 to 9 do
for d:=1 to cd[a]do
begin
inc(n); s[n]:= a*(100+10*d+d*d);
end;
Tim:= n;
end;
procedure Xem(n: integer): t vit
BEGIN
clrscr; n:= Tim; Xem(n);
writeln; write('Tong cong ',n,' so'); readln;
END.
// C#
using System;
using System.Collections;
namespace SangTao1
{
class SoCapNhan
{
static void Main(string[] args)
{
Show(Find());
Console.WriteLine("\n fini");
Console.ReadLine();
}
static ArrayList Find()
{
ArrayList s = new ArrayList();
int[] cd = {0,3,2,1,1,1,1,1,1,1};
for (int a = 1; a <= 9; ++a)
{
for (int d = 1; d <= cd[a]; ++d)
s.Add(a * (100 + 10 * d + d * d));
}
return s;
}
static void Show(ArrayList s) t vit
} // SoCapNhan
} SangTao1
Ch thch
15
16
c t
Trong TP hm random(n) sinh mt s ngu nhin kiu nguyn nm trong
khong t 0 n n - 1. Hy tng tng c mt qun sc sc n mt m s cc mt t
0 n n - 1. Khi ta gi hm random(n) th my tnh s gieo qun sc sc v
cho ta gi tr xut hin trn mt nga.
Trong C# phng thc Next(n) ca lp Random hot ng tng t nh
random(n) ca TP.
Ch
1. Trc khi gi hm random ta cn gi th tc randomize my tnh khi
ng c ch pht sinh s ngu nhin.
2. Th tc Gen(m) trong chng trnh di y sinh ngu nhin m s nguyn
trong khong t 0 n m - 1. Ta c th ci tin vit th tc Gen(n,d,c) sinh ngu nhin n s nguyn trong khong t d n c (d < c) nh sau.
rng random(cd+1) bin thin trong khong t 0 n cd, do
d+random(cd+1) s bin thin trong khong t d n d+cd = c.
(*
Pascal
*)
program RandomGen;
(*-----------------------------------------Sinh ngau nhien n so nguyen
khong am cho mang a
------------------------------------------- *)
{$B-}
uses crt;
const MN = 500;
var
a: array [1..MN] of integer;
n: integer;
Procedure Gen(m: integer);
var i: integer;
begin
randomize; n := m;
for i := 1 to n do a[i] := random(m);
end;
procedure Xem: t vit;
BEGIN
Gen(200); Xem;
END.
17
// C#
using System;
namespace SangTao1
{
class RandomGen
{
static void Main(string[] args)
{
Show(Gen(200));
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static int [] Gen(int n)
{
int [] a = new int[n];
Random r = new Random();
for (int i = 0; i < n; ++i)
a[i] = r.Next(n);
return a;
}
static void Show(int [] s): t vit
} // RandomGen
} // SangTao1
c t
Ta quy c vit #E l "tn ti" v #V l "vi mi". K hiu sum(a[d..c]) l tng cc
phn t lin tip nhau t a[d] n a[c] ca dy a:
sum(a[d..c]) = a[d] + a[d +1]+ ... + a[c].
Gi t l tng cc phn t ca mng: t = sum(a[1..n]).
Mun chia a thnh hai on a[1..i] v a[i+1..n] c tng bng nhau ta phi c:
1. t l s chn (t chia ht cho 2). t t2 = t div 2.
2. (#E i: 1 <= i <= n): sum(a[1..i]) = t2.
Chng trnh
Hm Chia cho gi tr i nu mng a chia c thnh a[1..i] v a[i+1..n].
Trong trng hp v nghim Chia = -1. Ta gi i l im chia v dng bin tr (tng
ring) tch lu tng cc phn t ca on ang xt a[1..i]. Khi tr = t2 bi ton c
nghim i. Ngc li, khi tr > t2 bi ton v nghim.
Ta khi tr ngu nhin cho mng a. Tuy nhin ta mun s ln c nghim (mng a
chia c thnh hai phn c tng bng nhau) xp x bng s ln v nghim. Ta s thc
hin mc tiu ra nh sau:
Mi ln khi tr ta tung ng xu hai mt. Nu gp mt sp (random(2)=0), ta s
khi tr ty cho mng a, ngc li, nu gp mt nga (random(2)=1) ta khi tr a
l mng c nghim.
khi tr sao cho mng a c nghim ta li chn ngu nhin mt im ct d trong
khong 1..(n/2). Sau ta khi tr ngu nhin cho cc phn t a[1..d]. Vi cc
phn t cn li ta cng khi tr ngu nhin trong khong hp l sao cho tng cc gi tr
18
(*
Pascal
*)
19
tr := tr + a[i];
if tr > t2 then exit; {vo nghiem }
if tr = t2 then { co nghiem i }
begin Chia:= i; exit; end;
end;
end;
procedure Test;
var i: integer;
begin
repeat
Gen(10); Xem; i := Chia;
if i = -1 then writeln('Khong chia duoc')
else
begin
writeln('Doan thu nhat: a[1..',i,']');
writeln('Doan thu hai: a[',i+1,'..',n,']');
end;
until ReadKey=Esc;
end;
BEGIN
Test;
END.
Ch
1. Mun dng chng trnh hy nhn phm Esc c m ASCII l #27.
2. Nu mng a c cha mt s gi tr 0 th bi ton c th c nhiu nghim
(nhiu cch chia).
//
C#
using System;
namespace SangTao1
{
class ChiaMangTiLe1_1
{
static void Main()
{
do {
Run(20);
Console.Write("\n Bam phim ENTER +
de tiep tuc, ");
Console.Write("\n Bam phim T de thoat: ");
} while (Console.ReadLine() == "");
}
static public void Run(int n)
{
int[] a = new int[n];
Gen(a, n); // sinh ngau nhien 1 test
Print(a, n);
int t = 0, d = Chia(a, n, ref t);
if (d < 0)
Console.WriteLine("\n Khong chia duoc");
else if (KiemTra(a, n, d))
{ Console.WriteLine("\n Doan thu nhat: 1..{0} ",d);
Console.WriteLine("\n Doan thu hai: {0}..{1} ",
d+1, n);
Console.WriteLine("\n Tong moi doan: " + t);
}
else Console.WriteLine("\n Loi giai sai!");
} // end Run
// Kiem tra sum(a[1..d] == sum(a[d+1..n]) ?
static public bool KiemTra(int[] a, int n, int d)
{ if (d < 0 || d >= n) return false;
int t = 0;
for (int i = 0; i < d; ++i) t += a[i];
for (int i = d; i < n; ++i) t -= a[i];
return (t == 0) ? true : false;
}
static public int Chia(int[] a, int n, ref int t)
{
int sum = 0; // sum = tong(a[1..n])
for (int i = 0; i < n; ++i)
sum += a[i];
if (sum % 2 != 0) return -1;
t = sum / 2; // tong moi doan
int tr = 0; // tong rieng
// doan 1: tr = sum a[1..i]
for (int i = 0; i < n; ++i)
{
tr += a[i];
if (tr == t) return i+1;
}
return -1;
}
// sinh ngau nhien n so ghi vao mang a
static public void Gen(int[] a, int n)
{
Random r = new Random();
if (r.Next(2) == 0)
{ // 1/2 so test la vo nghiem
for (int i = 0; i < n; ++i) a[i]=r.Next(n);
return;
}
// sinh mang a: sum(a[0..d-1])=sum(a[d..n-1])
int d = r.Next(n / 2) + 1; // diem chia
int t = 0;
// sinh doan a[0..d-1]
for (int i = 0; i < d; ++i)
{ a[i] = r.Next(n); t += a[i]; }
// sinh tiep doan a[d..n-1]
int n1 = n-1;
for (int i = d; i < n1; ++i)
{ a[i] = r.Next(t); t -= a[i]; }
a[n-1] = t; // phan tu cuoi
}
static public void Print(int[] a, int n): t vit
} // SoCapNhan
} // SangTao1
20
21
c t
Gi t l tng cc phn t ca dy a, t = sum(a[1..n])
Mun chia a thnh hai on a[1..i] v a[i + 1..n] c tng gp nhau k ln ta phi c:
1. t chia ht cho (k + 1). t t1 = t div (k + 1) v tk = t - t1.
2. (#E i: 1 <= i <= n): sum(a[1..i]) = t1 hoc sum(a[1..i]) = tk.
rng nu k = 1 th t1 = tk; nu k > 1 th t1 < tk, do bi ny l trng hp
ring ca bi trc khi k = 1.
Trong chng trnh di y, hm Chia(k) cho gi tr i nu mng a chia c
thnh hai on a[1..i] v a[(i + 1)..n] c tng gp k ln nhau. Trong trng hp v
nghim Chia = -1. Ta gi i l im chia v dng bin tr (tng ring) tch lu
tng cc phn t ca on ang xt a[1..i]. Khi tr = t1 bi ton c nghim I, ngc li,
khi tr > t1 ta cha th kt lun l bi ton v nghim. Trng hp ny ta phi tip tc
tch lu tr hi vng t c tng tr = tk. Nu sau khi tch lu ta thu c tr = tk th
bi ton c nghim i, ngc li, khi tr > tk ta kt lun l bi ton v nghim.
Function Chia(n,k: integer): integer;
var i: integer;
t, t1, tk, tr: longint;
begin
Chia := -1;
t := 0; { t = sum(a[1..n]) }
for i := 1 to n do t := t+a[i];
if (t mod (k+1) <> 0) then exit; { vo nghiem }
{ Xu li truong hop co nghiem }
t1 := t div (k+1); { doan tong nho }
tk := t - t1; { tk = k * t1}
tr := 0; { tong rieng tr = sum(a[1..i]) }
for i := 1 to n do
begin
tr := tr + a[i];
if (tr = t1) or (tr = tk) then
begin { lay nghiem i }
Chia:= i; exit;
end;
end;
end;
Ta gi th tc Gen sinh d liu kim th. Cng ging nh bi trc, ta s sinh
ngu nhin d liu kim th cho hai trng hp: chc chn c nghim v c th v
nghim. Vi trng hp c th v nghim ta sinh ngu nhin nh bnh thng,
for i := 1 to n do a[i] := random(n);
Vi trng hp c nghim, ta sinh ngu nhin mng a gm hai on:
on th nht a[1..d] v on th hai a[d + 1..n] trong d l mt im chia c
sinh ngu nhin
d := random(n div 2)+1; {diem chia}
Ta li chn ngu nhin mt trong hai trng hp:
(*
Pascal
*)
22
n := 10 + random(10);
k := random(5)+1;
writeln(nl,' n = ',n,' k = ',k);
Gen(n,k); Xem; i := Chia(n,k);
if i < 0 then writeln('Khong chia duoc')
else
begin
t := 0;
for j := 1 to i do t := t+a[j];
write('Doan 1: a[1..',i,'].');
writeln(' Tong = ',t);
t := 0;
for j:=i+1 to n do t := t+a[j];
write('Doan 2: a[',i+1,'..',n,'].');
writeln(' Tong = ',t);
end;
until ReadKey = Esc;
end;
BEGIN
Test;
END.
//
C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao1
{
/*------------------------------------------*
Chia Mang Ti Le 1:k
* Chia mang nguyen khomng am a[1..] thanh
*
hai doan ti le 1:k hoac k:1
* ------------------------------------------*/
class ChiaMangTiLe1_k
{
static void Main(string[] args)
{
do
{
Run(10, 3);
Console.Write("\n Bam RETURN de tiep tuc, ");
Console.Write("\n Bam T de thoat: ");
} while (Console.ReadLine() != "T");
}
static public void Run(int n, int k)
{
if (n < 0 || n > 1000000 || k < 1) return;
int[] a = Gen(n, k);
Print(a);
int d = Chia(a, k);
if (d < 0)
{
23
24
Console.WriteLine("\n Vo nghiem");
return;
}
Console.WriteLine("\n + Test(a, d, k));
}
// Kiem tra k*Sum(a[1..d]) = Sum(a[d+1..n]) ?
// hoac Sum(a[1..d]) = k*Sum(a[d+1..n])
static public bool Test(int[] a, int d, int k)
{
Console.WriteLine("\n\n Test, k = " + k);
Console.WriteLine("
Diem Chia = " + d);
int t1 = 0;
for (int i = 0; i < d; ++i) t1 += a[i];
int t2 = 0;
for (int i = d; i < a.Length; ++i) t2 += a[i];
Console.WriteLine("Sum1 = {0}, Sum2 = {1}",
t1, t2);
return (t1 == k * t2 || t2 == k * t1);
}
static public int Chia(int[] a, int k)
{
int t = 0;
foreach (int x in a) t += x;
if (t % (k + 1) != 0) return -1;
int t1 = t / (k + 1); // tong 1 phan chia
int t2 = t - t1; // tong phan con lai
int tr = 0; // tong rieng
for (int i = 0; i < a.Length; ++i)
{
tr += a[i];
if (tr == t1 || tr == t2) return i+1;
}
return -1;
}
static public int[] Gen(int n, int k)
{
Random r = new Random();
int[] a = new int[n];
if (r.Next(2) == 0)
{ // khoang 1/2 so test la vo nghiem
for (int i = 0; i < n; ++i)
a[i] = r.Next(n);
return a;
}
int d = r.Next(n / 2) + 1; //diem chia
int t = 0;
int d1 = d - 1;
for (int i = 0; i < d1; ++i)
{ a[i] = r.Next(n); t += a[i]; }
if (r.Next(2) == 0)
// doan dau a[1..d]
// gap k lan doan cuoi a[d+1..n]
a[d1] += (k - 1) * t;
25
26
CHNG 2
SINH D LIU VO V RA
c t
Ta vit th tc tng qut Gen(n,d,c) - sinh ngu nhin n s nguyn trong
khong t d n c (d < c) (xem bi gii 1.4). gii bi 2.1 ta ch cn gi
Gen(n,-M,M).
rng random(cd+1) bin thin trong khong t 0 n c-d do
d+random(cd+1) s bin thin trong khong t d n d+c-d = c.
(*----------------------------------------sinh ngau nhien n so nguyen trong khoang
d den c va ghi vao mang a
----------------------------------------- *)
Procedure Gen(n,d,c: integer);
var i,len: integer;
begin
randomize;
len := c-d+1;
for i:=1 to n do a[i]:= d+random(len);
end;
(*
Pascal
*)
//
C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao1
{
/*-------------------------------------*
Sinh ngau nhien n so
*
trong khoang d..c
* -----------------------------------*/
class RGen
{
static void Main(string[] args)
{
Print(Gen(20, -8, 8));
Console.ReadLine();
}
static public int[] Gen(int n, int d, int c)
{
Random r = new Random();
int len = c-d+1;
int [] a = new int[n];
for (int i = 0; i < n; ++i)
a[i] = d + r.Next(len);
27
28
return a;
}
static public void Print(int [] a)
{
Console.WriteLine();
foreach (int x in a)
Console.Write(x + " ");
Console.WriteLine();
}
} // RGen
} // SangTao1
Thut ton
1. Sinh ngu nhin phn t u tin: a[1] := random(n);
2. T phn t th hai tr i, tr c sinh bng tr ca phn t st trc n cng
thm mt i lng ngu nhin:
(i = 2..n): a[i] := a[i - 1] + random(n), do a[i] >= a[i - 1].
(*
Pascal
*)
//
C#
29
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao1
{
/*------------------------------------*
Sinh ngau nhien n so
*
tao thanh day khong giam
* ----------------------------------*/
class IncGen
{
static void Main(string[] args)
{
Print(Gen(200));
Console.ReadLine();
}
static public int[] Gen(int n)
{
Random r = new Random();
int [] a = new int[n];
a[0] = r.Next(5);
for (int i = 1; i < n; ++i)
a[i] = a[i-1] + r.Next(10);
return a;
}
static public void Print(int [] a) t vit
} // IncGen
} // SangTao1
c t
Xut pht t hon v n v a = (1, 2,..., n) ta i ch a[1] vi mt phn t tu (c
chn ngu nhin) a[j] s c mt hon v. Ta c th thc hin vic i ch nhiu ln.
(* Pascal
*)
// C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao1
{
/*--------------------------------*
Sinh ngau nhien hoan vi
*
1..n
* -------------------------------*/
class GenPer
{
static void Main(string[] args)
{
Print(Gen(20));
Console.ReadLine();
}
static public int[] Gen(int n)
{
Random r = new Random();
int[] a = new int[n];
for (int i = 0; i < n; ++i)
a[i] = i+1;
for (int i = 0; i < n; ++i)
{
int j = r.Next(n);
int t = a[0];
a[0] = a[j]; a[j] = t;
}
return a;
}
static public void Print(int [] a) t vit
30
31
} // IncGen
} // SangTao1
Thut ton
1. Chn s lng cc phn t trong mi on l random(n div k) + 1, khi
s lng cc phn t c pht sinh ngu nhin s khng vt qu
k*(n div k) n
Sau ta s chnh sao cho s lng cc phn t ng bng n.
2. Gi s a[d..c] l on th j cn c sinh ngu nhin sao cho
a[d] + a[d + 1] + ... + a[c] = t
Ta sinh on ny nh sau:
2.1. Gn tr := t; { tr - gi tr cn li ca tng }.
2.2. Gn tr ngu nhin 0..tr-1 cho cc phn t a[d..(c - 1)]
(i = d..c ): a[i] := random(tr)
2.3. ng thi chnh gi tr cn li ca tr:
tr := tr - a[i]
Ta c:
a[d] < t
a[d+1] < t - a[d]
a[d+2] < t - a[d+1] - a[d]
...
a[c - 1] < t - a[d] - a[d + 1] - ... - a[c - 2]
Chuyn v cc phn t a[*] trong biu thc cui cng, ta thu c
a[d] + a[d + 1] + ... + a[c 1] < t
2.4. Ta t gi tr cn li ca tng ring vo phn t cui on: a[c] :=
tr s thu c a[d] + a[d + 1] + ... + a[c] = t.
(*
Pascal
*)
begin
if (k < 1) or (k > n) then exit;
s := n div k;{s - so toi da phan tu trong moi doan}
i := 0; {chi dan lien tuc cho cac phan tu moi sinh}
for j := 1 to k do {sinh doan thu j}
begin
tr := t;
for p := 1 to random(s) do
{ random(s)+1 = so phan tu trong 1 doan }
begin
inc(i);
a[i] := random(tr);
tr := tr a[i]; {gia tri con lai cua tong}
end;
inc(i); {i phan tu cuoi cung cua doan j}
a[i] := tr;
end;
{bu 0 cho cac phan tu con lai}
for i := i+1 to n do a[i] := 0;
end;
procedure Xem(n: integer); Hin th mng a, t vit
procedure Test;
var n,k: integer;
begin
randomize;
repeat
n := random(30) + 1;
k := random(8) + 1;
t := random(30)+10;
writeln('n = ',n,' k = ',k,' t = ',t);
Gen(n,k,t); Xem(n);
until ReadKey = Esc;
end;
BEGIN
Test;
END.
// C#
using System;
using System.Collections.Generic;
using System.Text;
using System;
namespace SangTao1
{
class KGen
{
static void Main(string[] args)
{
Random r = new Random();
int n, k, t;
do
{
n = r.Next(30) + 1;
32
33
t = r.Next(30) + 1;
k = r.Next(8) + 1;
Console.WriteLine("\n n = " + n +
" k = " + k + " t = " + t);
Print(Gen(n, k, t));
Console.Write("\n Bam RETURN de tiep tuc: ");
} while (Console.ReadLine() == "");
}
// sinh n phan tu chia thanh k doan,
// moi doan co tong t
static public int[] Gen(int n, int k, int t)
{
if (k < 1 || k > n) return new int[0];
Random r = new Random();
int[] a = new int[n];
int s = n / k; // so phan tu trong 1 doan
int i = 0;
for (int j = 0; j < k; ++j)
{ // sinh doan thu j
int tr = t;
int endp = r.Next(s);
for (int p = 0; p < endp; ++p,++i)
{ a[i] = r.Next(tr); tr -= a[i]; }
a[i++] = tr;
}
// dien 0 cho du n phan tu
for (; i < n; ++i) a[i] = 0;
return a;
}
static public void Print(int[] a) t vit
} // KGen
} // SangTao1
Thut ton
1. Sinh ngu nhin tng t1 := random(n) + 1.
2. Tnh t2 := k*t1.
3. Gieo ng xu bng cch gi random(2) xc nh tng no trong s t1
v t2 c chn trc.
4. Sinh random(n div 2)+1 phn t cho on th nht sao cho tng cc
phn t ca on ny bng t1 (xem bi 2.4).
5. Sinh nt cc phn t cho on th hai sao cho tng cc phn t ca on ny
bng t2.
(*
Pascal
*)
program K2gen;
uses crt;
const MN = 1000;
34
END.
// C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao1
{
class K2Gen
{
static void Main(string[] args)
{
Random r = new Random();
int n, k;
do
{
n = r.Next(30) + 2;
k = r.Next(8) + 1;
Console.WriteLine("\n n = " + n +
" k = " + k);
int [] a = new int [n];
int n1 = Gen(a,n,k);
Print(a);
Test(a, n1, k);
Console.Write("\n Bam RETURN " +
" de tiep tuc: ");
} while (Console.ReadLine() == "");
}
// Kiem tra ket qua
static void Test(int[] a, int n1, int k)
{
int t1 = 0;
for (int i = 0; i < n1; ++i)
t1 += a[i];
Console.WriteLine("\n Doan thu nhat: " +
"sum(a[0.." + (n1 - 1) + "]) = " + t1);
int t2 = 0;
for (int i = n1; i < a.Length; ++i)
t2 += a[i];
Console.WriteLine("\n Doan thu hai: " +
"sum(a["+n1+".."+(a.Length - 1)+"]) = "+t2);
if ((t1 == k * t2) || (t2 == k * t1))
Console.WriteLine("\n DUNG");
else Console.WriteLine("\n SAI");
}
35
36
Thut ton
Bn c xem trc tip chng trnh v gii thch cch lm.
(*
Pascal
*)
// C#
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace SangTaoT1
{
class FincGen
{
static void Main(string[] args)
{
string fn = "Data.txt";
GenToFile(fn, 81);
Show(fn); Console.ReadLine();
}
static public void GenToFile(string fn, int n)
37
38
{
StreamWriter f = File.CreateText(fn);
Random r = new Random();
int x = r.Next(10);
for (int i = 0; i < n; ++i)
{
f.Write(x + " ");
// Moi dong 20 so
if (i % 20 == 19) f.WriteLine();
x += r.Next(10);
}
if (n % 20 != 19) f.WriteLine();
f.Close();
}
static public void Show(string fn)
{
Console.WriteLine(File.ReadAllText(fn));
}
} // FincGen
} // SangTao1
Thut ton
1. Sinh ngu nhin s hng th nht a[1] v cng sai d.
2. Sinh cc phn t a[i], i = 2..n
for i:=2 to n do a[i]:= a[i1]+ d;
3. Ghi file
phc tp: n.
(*
Pascal
*)
program FCapCong;
uses crt;
const BL = #32;
procedure Gen(fn: string; n: integer);
var f: text; i,d: integer; x: longint;
begin
assign(f,fn); rewrite(f);
randomize;
d := random(n div 4)+1; {cong sai }
x := random(20); write(f,x,BL);
for i:= 2 to n do
begin { mi dng ghi 20 s }
x:= x + d; write(f,x,BL);
if i mod 20 = 0 then writeln(f);
end;
if i mod 20 <> 0 then writeln(f);
close(f);
end;
BEGIN
39
// C#
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace SangTao1
{
class FCapCong
{
static void Main(string[] args)
{
string fn = "Data.txt";
GenToFile(fn, 81);
Show(fn); Console.ReadLine();
}
static public void GenToFile(string fn, int n)
{
StreamWriter f = File.CreateText(fn);
Random r = new Random();
int s = r.Next(n), d = r.Next(10)+1;
for (int i = 0; i < n; ++i)
{
f.Write(s + " ");
if (i % 20 == 19) f.WriteLine();
s += d;
}
if (n % 20 != 19) f.WriteLine();
f.Close();
}
static public void Show(string fn)
{
Console.WriteLine(File.ReadAllText(fn));
}
} // FcapCong
} // SangTao1
Thut ton
1. Sinh ngu nhin cc phn t trn ng cho chnh a[i,i],i=1..n.
2. Sinh ngu nhin cc phn t nm pha trn ng cho chnh a[i,j],
i=1..n, j=i+1..n ri ly i xng: a[j,i]:= a[i,j].
phc tp: n2.
(*
Pascal
*)
program GenMatSym;
uses crt;
const MN = 100;
var a = array[1..MN,1..MN] of integer;
procedure Gen(n: integer);
var i, j: integer;
begin
randomize;
for I := 1 to n do
begin
a[i,i] := random(n);
for j := i+1 to n do
begin
a[i,j]:=random(n); a[j,i]:=a[i,j];
end;
end;
end;
procedure Xem(n: integer);
var i, j: integer;
begin
writeln;
for i:= 1 to n do
begin
writeln;
for j:= 1 to n do write(a[i,j]:4);
end;
end;
BEGIN
Gen(20); Xem(20); readln;
END.
// C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SangTao1
{
class GenMatSym
{
static void Main(string[] args)
{
int n = 20;
int[,] a = Gen(n);
Print(a, n);
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public int [,] Gen(int n)
{
int[,] a = new int[n, n];
Random r = new Random();
for (int i = 0; i < n; ++i)
40
41
{
a[i, i] = r.Next(100);
for (int j=i+1; j<n; ++j)
{ a[i, j] = r.Next(100);
a[j, i] = a[i, j];
}
}
return a;
}
// hin th mng a[0..(n-1]
static public void Print(int [,] a,int n) t
vit
} // GenMatSym
} // SangTao1
Bi 2.9. S cao h
cao ca mt s t nhin l tng cc ch s ca s . Sinh ton b cc s
t nhin c ti a ba ch s v c cao h cho trc. Ghi kt qu vo mt tp
vn bn c tn cho trc.
Thut ton
Bi ton ny c cch pht biu khc v tng qut nh sau: c n cc nc dung tch
9 tha mi cc. Cho mt bnh ng h tha nc. Hy xc nh mi phng n chia
nc vo cc cc.
Ta xt li gii vi n = 3. Ta c h = 0..27.
1. Cc s cn tm y c dng y = abc, a + b + c = h v a bin thin t mina n maxa,
trong mina l lng nc t nht trong cc u tin a, maxa l lng nc ln nht trong
cc a. Nu y hai cc b v c, mi cc 9 tha nc th lng nc cn li s l ti thiu
cho cc a. Ngc li, nu tng cng ch c h < 9 tha nc th lng nc ti a trong cc a
phi l h. Ta c
if h 18 then mina := 0 else mina := h-18;
if h 9 then maxa := 9 else maxa := h;
2. Vi mi a = mina..maxa ta tnh
2.1. bc = h-a (bin bc cha tng cc ch s b v c).
2.2. Gii bi ton nh vi n = 2.
if bc 9 then minb := 0 else minb := bc-9;
if bc 9 then maxb := 9 else maxb := bc;
2.3. Vi mi b = minb..maxb ta tnh
y = 100*a + 10*b + (bc b).
Ghi s ny vo tp.
(* Pascal
*)
42
// C#
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace SangTao1
{
class HGen
{
static void Main(string[] args)
{
string fn = "HGen.txt";
int h = 10;
Console.WriteLine("\n File " + fn);
43
Ch
1. C th gii bi ton trn bng phng php vt cn dng ba vng for nh sau:
for a := 0 to 9 do
for b := 0 to 9 do
for c := 0 to 9 do
if a+b+c = h then
write(f,a,b,c,#32);
2. Phng php vt cn i hi 10*10*10 = 1000 ln duyt trong khi vi h = 10 ch
c 63 s tho mn iu kin ca u bi. Dng phng php sinh ta nhn c ng 63
s cn tm, khng phi duyt tha s no.
Bi 2.10. Tp cc hon v
44
Thut ton
1. Khi to v ghi hon v nh nht l hon v n v s [1..n] =
(1,2,...,n).
2. Gi s ta ghi c hon v s[1.n] vo tp. Hon v tip theo c to t s
thng qua hm Next nh sau:
2.1 Tm im gy: Tm ngc t s[n] tr v trc n v tr i u tin tho
iu kin s[i] < s[i + 1].
Nu khng tm c i tc l s l hon v ln nht, s[1..n] = (n,n1,..,1). t tr false cho hm Next v dng thut ton. Next =
false c ngha l khng tn ti hon v st sau hon v s hay s l hon v
ln nht.
Ch
Khi khi tr hon v n v ta s dng phn t s[0] = 0 lm lnh canh. Nh vy, khi
duyt ngc tm im gy ta khng phi kim tra gii hn mng. Thay v vit
i := n-1;
while (i > 0) and (s[i] > s[i+1]) do i:= i-1;
ta ch cn vit
i := n-1;
while (s[i] > s[i+1]) do i := i-1;
Hm Next c m t nh sau:
function Next(n: integer): Boolean;
var
i, j, t: integer;
begin
Next := false; i := n-1;
while (s[i] > s[i+1]) do i:= i-1;
if i = 0 then exit;
{ s[i] < s[i+1], i l im gy }
j := n; { Tm im vt a[j] > a[i] }
while (s[j] < s[i]) do j := j-1;
{ i ch s[i] , s[j] }
t:= s[i]; s[i]:= s[j]; s[j]:= t;
{ Lt s[i+1..n] } i:= i+1; j:= n;
while i < j do
begin
t:= s[i];s[i]:= s[j]; s[j]:= t;
i:= i+1; j:= j-1;
45
end;
Next:= true;
end;
Th d, vi n = 8, gi s ta ghi c hon v s = 74286531, khi hon v st
sau s s c xy dng nh sau:
S
7 4 2
Tm im gy: i = 3, v s[3] < s[4]
7 4 2
Tm im vt: j = 7, v s[7] > s[3]
7 4 2
7 4 3
i ch im gy v im vt: s[3] s[7]
Lt on s[4..8]
7 4 3
Quy trnh hot ng ca hm Next
74286531 74312568
(*
Pascal
8
8
8
8
1
6
6
6
6
2
5
5
5
5
5
*)
program GenAllPer;
{$B-}
uses crt;
const MN = 9; {max n} BL = #32; {dau cach}
var
s: array[0..MN] of integer;
function Next(n: integer): Boolean; t vit
procedure Gen(n: integer);
const
fn = 'HoanVi.dat'; {ten tep ket qua}
var
d: longint; {dem so luong hoan vi}
i: integer;
f: text; {tep ket qua}
begin
if (n < 1) or (n > MN) then exit;
assign(f,fn); rewrite(f);
d := 0; {dem so hoan vi}
{Sinh hon v n v. t lnh canh s[0] = 0}
for i := 0 to n do s[i]:= i;
repeat
d := d+1; {Ghi hoan vi thu d, s vao tep}
for i:= 1 to n do write(f, s[i], BL);
writeln(f);
until not (next(n));
writeln(f,' Tong cong ',d, ' hoan vi');
close(f);
end;
BEGIN
Gen(5); write('fini'); readln;
END.
// C#
using System;
using System.Collections.Generic;
using System.Text;
3
3
3
2
6
1
1
1
1
8
46
using System.IO;
namespace SangTao1
{
class GenAllPer
{
static void Main(string[] args)
{
string fn = "HoanVi.txt";
int d = Gen(fn,5);
Test(fn,d); // Xem kt qu
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
// Sinh cc hon v, ghi file fn
static public int Gen(string fn, int n)
{
if (n < 1 | n > 9) return 0;
int d = 0; // dem so hoan vi d = n!
StreamWriter f = File.CreateText(fn);
int[] a = new int[n + 1];
for (int i=0; i <= n; ++i) a[i]=i;
do {
// Ghi file
for (int i=1; i <= n; ++i)
f.Write(a[i] + " ");
f.WriteLine(); ++d;
} while (Next(a));
f.Close();
return d;
}
static bool Next(int[] a)//Hon v tip
{
int i, j, t, n = a.Length-1;
for (i=n-1; a[i] > a[i+1];--i) ;
if (i == 0) return false;
for (j = n; a[j] < a[i]; --j) ;
t = a[i]; a[i] = a[j]; a[j] = t;
for (++i, j = n; i < j; ++i, --j)
{ t = a[i]; a[i] = a[j]; a[j] = t; }
return true;
}
static public void Test(string fn, int d)
{
Console.WriteLine("\n Tong cong "
+ d + " so");
Console.WriteLine(File.ReadAllText(fn));
}
} // GenAllPer
} // SangTao1
47
- Tip n l cc d liu ghi lin tip nhau theo tng dng ca mng.
- Cc s cch nhau t nht mt du cch.
Th d:
2 3 -1 4 5 3 7 1
cho bit mng c n = 2 dng v m = 3 ct vi d liu nh sau:
-1
4
5
3
7
1
c t
Ta vit hm Doc cho gi tr true nu c c d liu. Ch rng d liu vo l
ng do khng cn kim tra tnh ng n ca chng. Nh vy Doc s cho gi tr
false trong trng hp khng m c file, do ghi sai ng dn hoc file
khng c to lp t trc.
Ch th {$I-} yu cu h thng ch ghi nhn ch khng bt cc li vo/ra, tc l
khng dng s thc hin chng trnh. Bin h thng IORESULT s ghi nhn s hiu
li. Nu IORESULT=0 th thao tc vo ra khng sinh li, ngc li, nu IORESULT
0 tc l c li.
Ch th {$I+} yu cu h thng bt mi li vo/ra. Nh vy, dng lnh
{$I-} reset(f); {$I+}
s c hiu nh sau:
Thot tin ta yu cu h thng b ch bt li vo/ra {$I-}. Sau thc hin
lnh m tp c reset(f).Tip n t li ch bt li {$I+}.
(*
Pascal
*)
uses crt;
const MN = 100;
var a: array[1..MN,1..MN] of integer;
m,n: integer;
Function Doc(fn: string): Boolean;
var
f: text;
i, j: integer;
begin
Doc := false; assign(f,fn);
{$I-} reset(f); {$I+}
if IORESULT <> 0 then exit; {khng m c file}
read(f,n,m);{doc kich thuoc n va m cua mang }
for i := 1 to n do
for j:= 1 to m do
read(f,a[i, j]);
close(f);
Doc := true;
end;
procedure Xem(n,m: integer); Hin th mng 2 chiu,
t vit
BEGIN
if Doc('DATA.INP') then Xem(n,m)
else write('Khong mo duoc tep ');
readln;
48
END.
// C#
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace sabgTao1
{
class DocMang2Chieu
{
static void Main(string[] args)
{
string fn = "Data.inp";
int n = 0, m = 0;
int [,] a = Doc(fn, ref n, ref m);
if (a != null)
{
PrintInput(fn);
Print(a, n, m);
}
else
Console.WriteLine("\n " +
" Khong mo duoc file " +fn);
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public int[,] Doc(string fn,
ref int n, ref int m)
{
if (!File.Exists(fn)) return null;
// Cac dau ngan
char[] cc = new char[]
{ ' ', '\n', '\t', '\r' };
// Mo tep ten fn doc, tch, dong tep
string[] ss = (File.ReadAllText(fn)).
Split(cc,
StringSplitOptions.RemoveEmptyEntries);
// Chuyn sang mng 1 chiu int [] c
int [] c = Array.ConvertAll(ss,
new Converter<string,int>(int.Parse));
n = c[0]; m = c[1];
int[,] a = new int[n, m];
int k = 2;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
a[i,j] = c[k++];
return a;
}
static void Print(int[,] a, int n, int m)
Hin th mng 2 chiu a, t vit
49
Gii thch
Trong cc my tnh hin i, b nh trong RAM ln c th cha ton b d
liu trong hu ht cc file input v th vi mi trng C# .NET bn nn c mt ln
d liu t cc file ny. Hm Doc cho ra mng nguyn hai chiu. Nu file khng tn ti,
hm cho ra gi tr null. Bn cn chun b trc file input vi tn Data.inp v ghi vo th
mc BIN\DEBUG trong Project hin hnh. Nu ghi file vo th mc khc th trong
tham bin fn phi ghi chi tit ng dn, th d D:\\MyDIR\\Data.inp. Khi
vit ng dn, thay v vit du \ ta phi vit hai du , tc l \\ v bn thn
du \ trong ng vai tr bo hiu k t ng st sau n l k t iu khin, th d,
\n biu th du xung dng. Bn cng c th vit du i mc @ cnh ng dn
ch th rng bn mun dng mt du \ thay v hai du, th d,
@D:\MyDIR\Data.inp
Lnh File.ReadAllText(fn) m file vi ng dn fn c ton b d liu
mt ln vo mt bin string sau t ng ng file.
Lnh Split(cc,StringSplitOptions.RemoveEmptyEntries)
tch cc n v trong bin string ghi vo bin string[] ss ng thi b i cc
du trng m t trong bin cc, bao gm du cch , du xung dng \n, du tab
\t v du kt RETURN \r, cui cng loi b cc n v rng, tc l cc string
khng cha k t no (Length = 0).
Lnh
int[] c = Array.ConvertAll(ss,
New Converter<string,int>(int.Parse));
chuyn cc string trong ss sang dng s nguyn v ghi vo mng nguyn (mt chiu)
c. n y ton b d liu trong file input fn c c v ghi vo mng nguyn c. Cc
mng trong C# c nh ch dn t 0 n Length-1. Theo iu kin ca u bi c[0]
cha gi tr n, c[1] cha gi tr m, t c[2] tr i cha ln lt cc gi tr trn cc dng
ca mng hai chiu.
Thut ton
4
7
5
1
50
1. M tp.
2. c gi tr u tin vo bin m: s lng ct ca ma trn.
3. Mi ln c xong mt dng ta tng con m dng (n) thm 1.
Ch
Do c th gp dng trng nn ta cn s dng hm SeekEof. Hm SeekEof
duyt tip t v tr hin thi ca con tr tp, b qua cc du trng (gm du cch, du
kt thc dng, du u dng, du nhy TAB), nu gp du ht tp th cho gi tr true,
ngc li, nu sau khi b qua cc du trng m cha gp du ht tp th cho gi tr
false.
(*
Pascal
*)
uses crt;
const MN = 100;
var
a: array[1..MN,1..MN] of integer;
m,n: integer;
Function Doc(fn: string): Boolean;
var f: text; j: integer;
begin
Doc := FALSE; assign(f,fn);
{$I-} reset(f); {$I+}
if IORESULT <> 0 then exit;
read(f,m); {m: so luong cot}
n := 0; {n: so luong dong}
while NOT SeekEof(f) do
begin
inc(n);
for j := 1 to m do read(f,a[n,j]);
end;
close(f);
Doc := TRUE;
end;
procedure Xem(n,m: integer); t vit
BEGIN
if Doc('DATA.INP') then Xem(n,m)
else write('Khong mo duoc tep ');
readln;
END.
Ch
Cn chun b trc d liu v ghi trong tp vn bn DATA.INP, th d:
DATA.INP
3 -1 4 5 3 7 1
//
C#
using
using
using
using
System;
System.Collections.Generic;
System.Text;
System.IO;
51
namespace SangTao1
{
class DocMang2
{
static void Main(string[] args)
{
string fn = "Data.inp";
int n = 0, m = 0;
int [,] a = Doc(fn, ref n, ref m);
if (a != null)
{
PrintInput(fn);
Print(a, n, m);
}
else Console.WriteLine("\n " +
" Khong mo duoc file " + fn);
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public int[,] Doc(string fn,
ref int n, ref int m)
{
if (!File.Exists(fn)) return null;
int [] c = Array.ConvertAll(
File.ReadAllText(fn).
Split(new char[] {' ','\n','\t','\r'},
StringSplitOptions.RemoveEmptyEntries),
new Converter<string,int>(int.Parse));
int k = 0;
m = c[k++]; n = (c.Length-1)/m;
int[,] a = new int[n, m];
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
a[i,j] = c[k++];
return a;
}
static void Print(int [,] a, int n, int m)
Hin th mng 2 chiu a[n,m], t vit
static public void PrintInput(string fn)
Hin th file fn; t vit
} // DocMang2
} // SangTao1
Gii thch
Bit s ct ca mng l m ta c th tnh ra s dng n ca mng theo cng thc
n = (c.Length-1) / m, trong c.Length cha s lng cc gi tr
c t file input, bao gm gi tr m v n.m gi tr ca mng, tc l
c.Length = n.m+1.
52
2
4
6
3
6
8
Thut ton
1. M tp.
2. c gi tr u tin vo bin n: s lng ct v dng ca ma trn vung i
xng.
3. Vi mi dng i ta c phn t trn ng cho chnh ca dng a[i, i], sau
ta c cc phn t nm bn phi a[i, i], tc l a[i, j] vi j = i + 1..n ri ly i xng
bng php gn a[j, i]:= a[i, j].
(*
Pascal
*)
uses crt;
const MN = 100;
var
a: array[1..MN,1..MN] of integer;
n: integer; { kich thuoc mang }
Function Doc(fn: string): Boolean;
var
f: text; i, j: integer;
begin
Doc := FALSE; assign(f,fn);
{$I-} reset(f); {$I+}
if IORESULT <> 0 then exit;
read(f,n);
for i := 1 to n do
begin
read(f,a[i,i]);
for j := i+1 to n do
begin
read(f,a[i,j]); a[j,i]:= a[i,j];
end;
end;
close(f); Doc:= TRUE;
end;
procedure Xem(n,m: integer); t vit
BEGIN
if Doc('DATA.INP') then Xem(n,n)
else write('Khong mo duoc tep ');
readln;
END.
// C#
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace SangTao1
{
class MangDoiXung
{
static void Main(string[] args)
{
string fn = "Data.inp";
int n = 0;
int [,] a = Doc(fn, ref n);
if (a != null)
{
PrintInput(fn);
Print(a, n);
}
else Console.WriteLine("\n " +
" Khong mo duoc file "+fn);
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public int[,] Doc(string fn,
ref int n)
{
if (!File.Exists(fn)) return null;
int [] c = Array.ConvertAll(
File.ReadAllText(fn).
Split(new char[] {' ','\n','\t','\r'},
StringSplitOptions.RemoveEmptyEntries),
new Converter<string,int>(int.Parse));
int k = 0; n = c[k++];
int[,] a = new int[n, n];
for (int i = 0; i < n; ++i)
for (int j = i; j < n; ++j)
a[i,j] = a[j,i] = c[k++];
return a;
}
1 1 1 1 0 0 1 1
static void
0 0 0 0 0 0 1 1
Print(int [,] a, int n)
Hin th mng 2
chiu a[n,n], t vit
static public void PrintInput(string fn)
Hin th file fn, t vit
} // MangDoiXung
} // SangTao1
Bi 2.14. m tu
53
1
1
54
Mt tp vn bn c tn fn c ghi s
1 1 0 0 0 0 0 0 0
mt vng bin hnh ch nht chiu ngang
1 1 0 0 1 1 0 0 1
250 k t, chiu dc (s dng) khng hn
5 tu
ch. Trn bin c cc con tu hnh ch
nht cha cc k t 1, vng nc c biu th qua cc k t 0. Bit rng cc
con tu khng dnh nhau. Hy m s lng tu.
V d, hnh bn c 5 tu.
Thut ton
V cc tu khng dnh nhau nn ta phn bit cc tu qua mi tu, tc l gc A - gc
Ty-Bc ca tu. Ta c,
s lng tu = s lng mi tu
Mi tu l im nhn gi tr 1 v nu bc mt bc sang tri hoc ln trn s ln
b hoc ri xung bin.
Sau khi m tp ta c v x l tng dng vn bn y v so snh n vi dng x x
l trc . Nu y l dng u tin, tc l dng nm st b Bc, ta khi tr cho x vi 250
ks t 0 tc l ta loi tr trng hp bc ln b Bc. Khi x l y, ta ch tch ring
trng hp tu nm st b Ty, tc l xt ring y[1]. Sau mi ln x l dng y ta copy
dng y sang x v lun gi cho x c chiu di ti a 250 k t nh yu cu ca u bi.
(*
Pascal
*)
A 0 0 0 0 0
program Ships;
{$B-}
0 1 1 1 1 1
uses crt;
0 1 1 1 1 1
const MN = 250;
boong = '1'; nuoc = '0';
D 0 0 0 0 0
Function Dem(fn: string):
integer;
Con tu ABCD
var
f: text; d,i: integer;
x,y: string;{x:dong tren, y:dong duoi }
begin
Dem := 0; assign(f,fn);
{$I-} reset(f); {$I+}
if IORESULT <> 0 then exit;
x := nuoc;
for i := 1 to 8 do x:= x+x; {x = 00...0}
d := 0;
while NOT EOF(f) do
begin
readln(f,y);
if (y[1]=boong)AND(x[1]=nuoc) then d:=d+1;
for i:=2 to length(y) do
if (y[i]= boong) AND (y[i-1]= nuoc)
AND (x[i]= nuoc) then d:=d+1;
x := y;
end;
Dem := d;
end;
BEGIN
n:= Dem('TAU.INP');
if n=0 then
write('Khong mo duoc tep/khong co tau')
else write('Tong so tau: ',n);
readln;
END.
// C#
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace SangTao1
{
class Ships
{
static public string fn = "Tau.inp";
static public string gn = "Tau.out";
static public char boong = '1';
static public char nuoc = '0';
static void Main(string[] args)
{
Save(Count());
Test();
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public int Count()// dem tau
{
StreamReader f = File.OpenText(fn);
string x = new string(nuoc,251);
string y;
string empty = "";
int d = 0;
while ((y=(f.ReadLine()).Trim())
!= empty)
{
d += Scan(x, y); x = y;
}
f.Close(); return d;
}
// Snh dng tren x vi dng di y
static public int Scan(string x, string y)
{
int d = 0;
if ((y[0]==boong)&&(x[0]==nuoc)) ++d;
for (int i = 1; i < y.Length; ++i)
55
56
if ((y[i]==boong)&&(y[i-1]==nuoc)
&& (x[i]==nuoc)) ++d;
return d;
}
static public void Save(int d) // ghi file
{ File.WriteAllText(gn, d.ToString()); }
static public void Test()
{
Console.WriteLine("\n" +
File.ReadAllText(fn) + "\n");
Console.WriteLine("\n" +
File.ReadAllText(gn) + "\n");
}
} // Ships
} // SangTao1
Bi 2.15. Sp on
Trong mt tp vn bn cha nhng on ct ra t mt trc s. Mi on c dng
<d, c> trong "<" c th l mt trong hai k t ( hoc [, > c th l mt trong
hai k t ) hoc], d v c l cc biu thc dng x hoc x + y hoc x*y vi x v y l
nhng s t nhin. Ta lun c d c. Chiu di ca on <d, c> l hiu c - d.
Hy sp xp cc on tng theo chiu di v ghi chng vo mt tp vn bn theo
ng dng thc c c ca mi on. C th thm, bt mt s du cch trong
v ngoi cc on. Trn mi dng ca tp lun lun cha trn mt s on.
Th d cho d liu vo trong file input Doan.inp l:
[2+1,7) (4,4*3) (5,6]
Sau khi sp ta c kt qu sau trong file output Doan.out:
(5,6] [2+1,7) (4,4*3)
Thut ton
Ta m t cu trc ca mi on nh sau:
mo so1[toan1 so2] , so3[toan2 so4]
trong :
mo l mt trong hai du m ngoc: ( hoc [.
so1, so2, so3 v so4 l cc s t nhin xut hin trong thnh phn ca
on.
toan1 v toan2 l du cc php ton (+, *), nu c trong thnh phn
ca on.
dong l mt trong hai du ng ngoc: ) hoc].
Trong m t trn, chng ta s dng k php [*] ch ra thnh phn * c th b
qua.
Nu thnh phn th i (i = 1..2) ca on khng c du php ton, th cng khng c
ton hng th hai, tc l thnh phn c dng l mt s t nhin th ta t toan[i] =
BL (du cch).
Nu s th i khng xut hin trong on, ta t so[i] = 0.
Th d:
on
mo
so1
Toan1
so2
so3
Toan2
so4
dong
57
[2+10,7*6)
[2+10,7)
(2,7+5]
[
[
(
2
2
2
+
+
BL
10
10
0
7
7
7
*
BL
+
6
0
5
)
)
]
58
Mi ln bn s mt k t c no ri da vo k t bn xc nh cc th tc cn thc
hin nhn bit tng i tng. Mun vy ta s dng mt bin gi l bin trng thi q
vi mc ch ghi nhn cc tnh hung gp v trn c s xc nh cc thao tc cn
thit. Gi q l bin trng thi. Trong qu trnh c v x l tp input ta c th gp nm
trng thi nh sau:
q = 0: Trng thi d tm u on: Nu gp k t m u mt on, c th l nu gp
k t c = '(' hoc c = '[' th cn to mt on mi nh sau:
59
(*
Pascal
*)
{$B-}
program Segments;
uses crt;
const
fn = 'DOAN.INP'; {Tep input}
gn = 'DOAN.OUT';{Tep output}
MN = 1000; {So luong toi da cac doan}
BL = #32;{Dau cach}
ChuSo = ['0'..'9'];
PhepToan = ['+','*'];
type
MangSo = array[1..4] of integer;
MangToan = array[1..2] of char;
KieuDoan = record
mo: char; {dau mo ngoac}
dong: char; {dau dong ngoac}
so: MangSo; {4 so trong doan}
Toan: MangToan; {2 phep toan}
len: integer; {chieu dai doan}
end;
MangDoan = array[0..MN] of KieuDoan;
const
KhoiTriSo: MangSo = (0,0,0,0);
KhoiTriToan: MangToan = (BL,BL);
var
f,g:text;
a: MangDoan;
c: char;{ky tu dang xet}
n: integer;{chi so doan dang xet}
q: integer;{bien trang thai}
(*--------------------------------Cac trang thai q = 0: do tim dau doan
1: doc so[1]
2: doc so[2]
3: doc so[3]
4: doc so[4]
-----------------------------------*)
procedure LenSeg(i: integer); t vit
procedure KetDoan; t vit
(*----------------------------------------Them 1 chu so vao so thu j cua doan i
------------------------------------------*)
procedure DocSo(i,j: integer);
begin
a[i].so[j]:=a[i].so[j]*10+(ord(c)-ord('0'))
end;
(*-------------------------------------Doc cac doan
---------------------------------------*)
procedure doc;
begin
assign(f,fn); reset(f);
q:=0; n:=0;
while not eof(f) do
begin
read(f,c);
case q of
0: if c in['(','['] then
begin
n:=n+1; a[n].mo:=c;
a[n].so:=KhoiTriSo;
a[n].Toan:=KhoiTriToan;
q:=1;
end;
60
61
62
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTao1
{
class SapDoan
{
static public string fn = "Doan.inp";
static public string gn = "Doan.out";
static public string s; // du lieu vao
static public Doan[] d = new Doan[5000]; // cac doan
static public int n = 0; // so luong doan
static public char Ket = '#';
static void Main(string[] args)
{
s = File.ReadAllText(fn) + Ket.ToString();
Console.WriteLine("\n Du lieu " +
"truoc khi xu li:\n " + s);
n = DocDoan();
Console.WriteLine("\n Tong cong " + n + " Doan");
Console.WriteLine(n); Printd();
QSort(d, 0, n-1);
Console.WriteLine("\n Da sap: "); Printd();
Ghi(); XemLai();
Console.WriteLine("\n Fini ");
Console.ReadLine();
}
static public void XemLai()
{
Console.WriteLine("\n Kiem tra lai:\n");
Console.WriteLine("\n Input:\n" +
File.ReadAllText(fn));
Console.WriteLine("\n Output:\n" +
File.ReadAllText(gn));
}
static public int DocDoan()
{
int
int
int
int
for
{
n = -1;
q = 0; // trang thai
i = 0; // bien tro trong s
dau, cuoi;
(; s[i] != Ket; ++i)
switch(q)
{
case 0: // Tim dau doan
if (GapMo(s[i]))
{
++n; d[n] = new Doan();
d[n].Mo = s[i]; q = 1;
}
break;
case 1: // Doc so1
if (GapSo(s[i]))
d[n].So1 = DocSo(ref i);
else if (GapToan(s[i]))
{d[n].Toan1 = s[i]; q = 2;}
else if (s[i]==',') q = 3;
break;
case 2: // Doc so2
if (GapSo(s[i]))
d[n].So2 = DocSo(ref i);
else if (s[i]==',') q = 3;
break;
case 3: // Doc so3
if (GapSo(s[i]))
d[n].So3 = DocSo(ref i);
else if (GapToan(s[i]))
{
d[n].Toan2 = s[i]; q = 4;
}
else if (GapDong(s[i]))
q = 5;
break;
case 4: // Doc so4
if (GapSo(s[i]))
d[n].So4 = DocSo(ref i);
else if (GapDong(s[i]))
q = 5;
break;
case 5: // Xong 1 doan
d[n].Dong = s[--i];
dau = d[n].So1;
if (d[n].Toan1 == '+')
dau += d[n].So2;
else if (d[n].Toan1 == '*')
dau *= d[n].So2;
cuoi = d[n].So3;
if (d[n].Toan2 == '+')
cuoi += d[n].So4;
63
64
65
66
CHNG 3
BN PHM V MN HNH
Ch
ASCII (c l a-ski) l b m chun dng trong trao i thng tin ca M v u tin
c ci t trong cc my tnh s dng h iu hnh MS-DOS. Trong bng m ny, mi
k t c mt m s ring bit chim 1 byte. Trong TP Ta vit 65 l biu th m s 65,
vit #65 l biu th k t c m s 65, tc l ch 'A'. Cc k t mang m s t 0 n
31 l cc k t iu khin, th d, k t #13 iu khin con tr vn bn xung dng mi,
k t #10 iu khin con tr vn bn v u dng. Nh vy, xu k t #13#10 s iu
khin con tr v u dng mi v do lnh write(#13#10) s tng ng vi lnh
writeln. Lnh writeln(#13#10) s tng ng vi hai lnh writeln;
writeln.
Chng trnh di y ghi vo tp vn bn c tn ASCII.DAT cc k t v m ca
chng. Tt c c 256 k t chia lm hai phn. 128 k t u tin m s t 0 n 127 l
cc k t c s, 128 k t cn li, m s t 128 n 255 l cc k t m rng.
Sau khi thc hin chng trnh, bn c th m tp ASCII.DAT xem tng k t
v m ca chng. Lu rng c k t hin th c v c k t khng hin th c trn
mn hnh, chng hn nh cc k t iu khin.
(*
Pascal
*)
program ASCII;
uses crt;
procedure ASCII;
var f: text; i: byte;
begin
assign(f,'ASCII.DAT');
rewrite(f);
for i := 0 to 255 do
67
begin
write(f,chr(i), ': ',i:3,' ');
if i mod 5 = 0 then writeln(f);
end;
close(f);
writeln('OK'); readln;
end;
BEGIN
ASCII;
END.
// C#
Chng trnh di y lu li m ca 128 k t u tin ng vi phn c s ca
bng m ASCII. Cc k t phn m rng ph thuc vo tng phin bn ci t ca cc
h iu hnh.
using System;
using System.IO;
namespace SangTao1
{
class ASCII
{
static void Main()
{
string fn = "ASCII.TXT";
StreamWriter g = File.CreateText(fn);
for (int i = 0; i < 128; ++i)
g.WriteLine("{0}: {1}", i, (char)i);
g.Close();
Console.WriteLine(File.
ReadAllText(fn)); // Doc lai
Console.ReadLine();
}
} // class
} // space
Bi 3.2. B T l kh
Lp chng trnh hin th trn mn hnh cc qun bi T l kh gm R, C,
Pch, Nhp theo quy nh qun A mang m s 1 v c 1 hnh n v, cc qun
m s i t 2 n 10 c i hnh n v, cc qun J, Q v K ln lt c 11, 12 v
13 hnh n v tng ng. Hnh n v gm bn loi k t c m ASCII tng
ng nh sau:
(R) : #4, (C) : #3, (Pch): #6, (Nhp): #5.
8
68
Ba qun bi T l kh
Gi
Trc ht ta cn thng nht mt s quy nh sau:
Qun bi c v bng mt mu M ty chn.
Nu l qun R hoc C ta t mu ch l (RED), vi cc qun Pch v
Nhp ta t mu ch l en (BLACK).
Mi qun bi c hai thuc tnh l loi (R, C, Pch hoc Nhp) v m s. M
s ca qun A l 1, J l 11, Q l 12 v K l 13. Cc qun cn li mang m s
t 2 n 10 ng vi s ghi trn qun bi .
Trn nn cc qun bi J, Q v K khng v hnh ngi m v s lng hnh n
v (R, C, Pch hoc Nhp) tng ng vi m s ca qun .
b tr s lng hnh n v trn mi qun bi cho cn i ta cn 5 dng. Th tc
Dong(q:char;s:string;x,y:byte) v 5 dng cha hnh n v loi q, bt u
tnh t to (x, y) ng vi v tr gc trn tri ca qun bi trn mn hnh, theo du hiu ghi
trong xu mu s. Th d, li gi vi xu mu s = '20302' s v 5 dng th hin cho qun
mang m s 7 thuc loi v (R, C, Pch hoc Nhp) nh sau:
1. Dng th nht c 2 k t v.
2. Dng th hai c 0 k t v tc l trng.
3. Dng th ba c 3 k t v.
4. Dng th t c 0 k t v tc l trng.
5. Dng th nm c 2 k t v.
V trong xu mu s tng cng c 2 + 3 + 2 = 7 k t v nn qun bi mang m s 7.
procedure Dong(v: char;s: string;x,y: byte);
var i: byte;
begin
x := x+3; y := y+TY;
for i := 1 to 5 do
begin
gotoxy(x,y);
case s[i] of
'1': write(BL,BL,v,BL,BL);
'2': write(v,BL,BL,BL,v);
'3': write(v,BL,v,BL,v);
end;
y := y+TY;
end;
end;
Cc mu dng s c tnh ton trc v khi tr nh sau:
MauDong: array[1..13] of string[5] =
('00100', '01010', '10101', '20002', '20102',
'20202', '20302', '21212', '30303', '22222',
'22322', '23232', '23332');
Ta d dng nhn ra c tt c 13 mu dng ng vi 13 m s 1(A), 2,..., 10, 11(J), 12(Q)
v 13(K). Tm li mu dng th i cho ta phng thc v i hnh n v trn qun bi mang
m s i. Mi mu dng c biu din qua mt xu 5 k t.
69
DOS
9
12
2
9
6
1
(*
Pascal
*)
uses crt;
const
CO = #3; RO = #4; NHEP = #5; PIC = #6;
WIND = 1; DOS = 2; BL = #32;
DX: byte = 9;
DY: byte = 12; {kich thuoc quan bai}
TY: byte = 2;
MauDong: array[1..13] of string[5] = ('00100',
'01010',
'10101',
'20002',
'20102',
70
'20202',
'20302',
'21212',
'30303',
'22222',
'22322',
'23232',
'23332');
Nhan: array[1..13] of string[2]
= ('A','2','3','4','5',
'6','7','8',9', 10',
'J','Q','K');
procedure Dong(q: char;s: string;x,y: byte); t vit
{--------------------------------Ve nen mau M cho quan bai
tai vi tri goc tren trai (x,y)
--------------------------------}
procedure Nen(M,x,y: byte);
var i: byte;
begin
TextBackGround(M);
for i:= 0 to DY do
begin
gotoxy(x+1,y+i);
write(BL:DX);
end;
end;
{---------------------------------------------Ve 1 quan bai kieu q (ro, co, bich, nhep);
so n (2 ... 10; 1 = A; 11 = J; 12 = Q; 13 = K)
goc Tay-Bac tai cot x, dong y cua man hinh,
---------------------------------------------}
procedure VeQuanBai(q: char; n, x, y: byte);
var i, j: byte;
begin {VeQuanBai}
if (q = RO) OR (q = CO) then TextColor(RED)
else TextColor(BLACK);
Nen(WHITE,x,y);
Dong(q,MauDong[n],x,y);
{viet so}
gotoxy(x+1,y+1); write(Nhan[n]:2);
gotoxy(x+DX-1,y+DY-1); write(Nhan[n]);
end;
Procedure VeBai(Kieu: byte);
var i: integer;
begin
if Kieu = DOS then
begin
DY:= 6;
TY:= 1;
end else
if Kieu = WIND then
begin
DY:= 12;
TY:= 2;
end else
begin
writeln('Dat kieu khong dung');
write('Cach goi thu tuc: ');
writeln('VeBai(WIND) hoac VeBai(DOS)');
readln; halt;
end;
textbackground(BLUE); clrscr;
for i := 1 to 13 do {Ve bo Tu lo kho}
begin
VeQuanBai(RO,i,5,10);
VeQuanBai(CO,i,20,10);
VeQuanBai(PIC,i,35,10);
VeQuanBai(NHEP,i,50,10);
if ReadKey=#27 then halt;
end;
textattr:= 7; clrscr;
end;
BEGIN
VeBai(WIND);
END.
// C#
using System;
using System.IO;
namespace SangTao1
{
/*------------------------------*
Bo bai Tulokho
* -----------------------------*/
class TuLoKho
{
static void Main()
{
BoBai b = new BoBai();
b.Draw(6, 4);
Console.ReadLine();
}
} // Class
/*----------------------------------*
Mo ta bo bai Tulokho
* ---------------------------------*/
class BoBai
{
private char CO = (char)3;
private char RO = (char)4;
private char NHEP = (char)5;
private char PIC = (char)6;
71
const int DX = 9;
const int DY = 6;// kich thuoc quan bai
// 1 khoang cach giua 2 dong
const int TY = 1;
const int SOQUAN = 13;
private string[] MauDong = {"00100",
"01010",
"10101",
"20002",
"20102",
"20202",
"20302",
"21212",
"30303",
"22222",
"22322",
"23232",
"23332"
};
private string[] Nhan = {"A","2","3","4","5","6","7",
"8","9","10","J","Q","K"};
// Dat mau nen va text cho man hinh
private void SetColors(ConsoleColor bg, ConsoleColor fg)
{
Console.BackgroundColor = bg;
Console.ForegroundColor = fg;
}
// Viet s tai cot x, dong y
private void WriteAt(string s, int x, int y)
{
Console.SetCursorPosition(x, y);
Console.Write(s);
} // WriteAt
// Ve bo bai tai vi tri x, y
public void Draw(int x, int y)
{
int DD = DX + 10;
Console.BackgroundColor =
ConsoleColor.Blue;
Console.Clear();
for (int i = 0; i < SOQUAN; ++i)
{
VeQuanBai(RO, i, x, y);
VeQuanBai(CO, i, x + DD, y);
VeQuanBai(PIC, i, x + 2 * DD, y);
VeQuanBai(NHEP, i, x + 3 * DD, y);
Console.ReadLine();
}
Console.ResetColor(); // tra lai nen cu
} // Draw
/*-------------------------------------Ve 5 dong trong quan bai
--------------------------------------*/
private void Lines(char q, string s,
72
73
int x, int y)
{
const string BL = " ";
string qs = q.ToString();
x += 3;
for (int i = 0; i < 5; ++i)
{
y += TY;
Console.SetCursorPosition(x, y);
switch (s[i])
{
case '1':
Console.WriteLine(BL + BL + qs + BL + BL);
break;
case '2':
Console.WriteLine(qs + BL + BL + BL + qs);
break;
case '3':
Console.WriteLine(qs + BL + qs + BL + qs);
break;
} // switch
} // for
}
// Dat mau nen cho quan bai
private void Nen(ConsoleColor m,
int x, int y)
{
string s = new string(' ', DX);
Console.BackgroundColor = m;
for (int i = 0; i <= DY; ++i)
WriteAt(s, x + 1, y + i);
}
/*-------------------------------------------Ve 1 quan bai kieu q (ro, co, bich, nhep);
so n (1 ... 10; 0 = A; 10 = J; 11 = Q; 12 = K)
goc Tay-Bac tai cot x, dong y cua man hinh,
--------------------------------------------*/
private void VeQuanBai(char q, int n, int x, int
y)
{
// Chon mau chu RO, CO: mau do
// PIC, NHEP: mau den
Console.ForegroundColor =
(q == RO || q == CO)
? ConsoleColor.Red
: ConsoleColor.Black;
// Dat nen quan bai mau trang
Nen(ConsoleColor.White, x, y);
// Ve 5 dong
Lines(q, MauDong[n], x, y);
// Viet so o goc tren-trai
74
Ch thch
Cc tham s x, y v DX, DY ph thuc vo phn gii mn hnh. Bn cn iu
chnh cc tham s ny cho ph hp vi ch phn gii mn hnh chn.
Bi 3.3. Hm GetKey
Mi khi ta nhn mt phm, trong vng m 2 byte s c np 1 hoc 2 byte tu
theo kiu phm nhn. Nu l phm thng nh a, b, c, %, $,... trong vng m s
c np 1 byte cha m ASCII ca k t tng ng. Nu ta nhn phm m rng
nh F1,..., F10, cc phm dch chuyn con tr, , , , , Ins (chn), Del (xo),
PageUp/PgUp (ln mt trang), PageDown/PgDn (xung mt trang),... trong vng
m s c np hai byte, byte th nht c gi tr 0, byte th hai cha m ring
ca phm nhn. M ring ny c th trng vi m ca cc k t thng. Th d,
khi ta nhn phm m rng F10 trong vng m s c np 2 byte (0, 68). M
ring 68 trng vi m ca k t D. Hm ReadKey cho ta k t ca phm nhn v
khng hin th k t (trn mn hnh), ta gi l hm nhn thm mt k t.
ReadKey trc ht kim tra vng m bn phm xem cn byte no cha c c
khng. Nu cn, ReadKey s c byte . Ngc li, nu vng m trng, ReadKey
s ch ta nhn mt phm ri sau c 1 byte t vng m.
Hy vit hm GetKey cho ra m ASCII ca phm thng nhn v cho ra m
ring ca phm m rng cng thm 128 nhm phn bit c phm thng vi
phm m rng.
Ch : Hm GetKey bi 3.3 cho m ca mt s phm m rng dng iu
khin con tr mn hnh nh sau:
LEN:
200
Mi tn tr ln
XUONG:
208
Mi tn tr xung
PHAI:
205
Mi tn tr qua phi
TRAI:
203
Mi tn tr qua tri
ESC (27) v ENTER/RETURN (13) l nhng phm thng.
Gi
Trc ht gi hm c:= ReadKey ri kim tra gi tr ca k t c. Nu c c m 0
tc l nhn phm m rng, ta cn c tip byte th hai v gn cho hm gi tr ca
byte cng thm du hiu nhn bit phm m rng l 128. Nu c c m khc 0, ta gn
cho hm gi tr .
(*
Pascal
*)
(* ----------------------Ham GetKey
-------------------------*)
program Conio;
75
uses crt;
const Esc = 27;
Function GetKey: integer;
var c: char;
begin
c:= ReadKey;
if c <> #0 then GetKey := Ord(c)
else GetKey := Ord(ReadKey) + 128;
end;
Procedure Test;
var k: integer;
begin
repeat
write(' Nhan Phim (Bam ESC de thoat): ');
k:= GetKey;
if k > 128 then
writeln(' Phim mo rong (0, ',k-128,') ==> ',k)
else
writeln(' Phim thuong ',chr(k), '(',k,')');
until k = Esc;
readln;
end;
BEGIN
Test;
END.
Bi 3.4. Tr chi 15
C 15 qun c c nh m s t 1 n 15 c t trong mt bn c hnh vung 4
4 theo hnh trng ban u nh rong hnh . Mi bc i, ta c php di chuyn
mt qun nm cnh trng vo trong trng.
1
10
11
12
13
14
15
Tr chi 15
Vit chng trnh thc hin hai chc nng sau y:
a) o ngu nhin cc qun c chuyn t hnh trng ban u v mt hnh trng
H no .
b) Nhn phm iu khin ca ngi chi ri di chuyn qun c theo phm . Khi
no ngi chi t c hnh trng ban u th kt thc mt vn.
Tr chi ny c tn l Tr chi 15, tng ni ting th k XIX nh tr chi Rubic
thi i chng ta vy.
Gi
76
(*
Pascal
*)
(*---------------------Game 15
-----------------------*)
uses crt;
const
BL = #32;
DD = 4;
x = 2; y = 3; {Goc Tay-Bac cua ban co}
dx = 2; dy = 3; {Khoang cach giua cac o}
{cac ma dich chuyen con tro}
LEN = 200;
XUONG = 208;
PHAI = 205;
TRAI = 203;
var
a, b: array [1..DD,1..DD] of byte; {ban co}
xx, yy: byte; {Toa do cua con tro}
{-----------------------Nhan tham 1 ki tu
-------------------------}
Function GetKey: integer;
var c: char;
begin
c:= ReadKey;
if c <> #0 then GetKey:= Ord(c)
else
begin
c:= ReadKey;
GetKey:= Ord(c) + 128;
end;
end;
{------------------------Chuyen con tro man hinh
den vi tri hien thi
quan co (i,j)
--------------------------}
procedure Den(i,j: byte);
begin
Gotoxy(y+(j-1)*dy,x+(i-1)*dx);
end;
{----------------------------Viet gia tri cua quan co
a[i,j] vao o tuong ung
------------------------------}
procedure Viet(i,j: byte);
begin
Den(i,j);
if a[i,j] = 0 then
begin
TextBackGround(YELLOW);
write(BL:2);
TextBackGround(BLUE);
end
else write(a[i,j]:2);
end;
{------------------------------Khoi tri:
1. Dat mau chu, mau nen
77
2. Ve ban co
-------------------------------}
procedure Init;
var i, j, k: byte;
begin k := 0;
{nen ngoai mau vang}
TextBackGround(YELLOW);
Gotoxy(1,1);
{ Ve cac o trong }
for i:= 1 to dx*DD+1 do
begin
for j := 1 to dy*DD+3 do write(BL);
writeln;
end;
TextBackGround(BLUE); {nen ban co mau xanh}
TextColor(WHITE); {chu trang}
{Khoi tri va hien thi cac quan co}
for i:= 1 to DD do
for j:= 1 to DD do
begin
inc(k); a[i,j]:= k;
b[i,j]:= k; Viet(i,j);
end;
a[DD,DD]:= 0; b[DD,DD]:= 0;
Viet(DD,DD); Den(DD,DD);
xx:= DD; yy:= DD;
end;
{-----------------------------Di chuyen quan co a[xx,yy]
vao o trong ke no
-------------------------------}
procedure Chuyen(k: integer);
begin
case k of
0: {LEN}
if xx < DD then
begin
a[xx,yy]:= a[xx+1,yy];
Viet(xx,yy);
inc(xx); a[xx,yy]:= 0;
Viet(xx,yy);
end;
1: {XUONG}
if xx > 1 then
begin
a[xx,yy]:= a[xx-1,yy];
Viet(xx,yy);
dec(xx); a[xx,yy]:= 0;
Viet(xx,yy);
end;
2: {PHAI}
if yy > 1 then
begin
78
a[xx,yy]:= a[xx,yy-1];
Viet(xx,yy);
dec(yy); a[xx,yy]:= 0;
Viet(xx,yy);
end;
3: {TRAI}
if yy < DD then
begin
a[xx,yy]:= a[xx,yy+1];
Viet(xx,yy);
inc(yy); a[xx,yy]:= 0;
Viet(xx,yy);
end;
end;
end;
{----------------------------Dao ngau nhien cac quan co
------------------------------}
procedure DaoNgauNhien;
var c: integer;
begin
repeat
Chuyen(random(4));
Delay(50); {Dat do tre de kip quan sat}
until KeyPressed;
c:= GetKey;
end;
{-------------------------Kiem tra ban co a co
trung voi cau hinh chuan ?
----------------------------}
function Dung: Boolean;
var i, j: byte;
begin
Dung:= FALSE;
for i:= 1 to DD do
for j:= 1 to DD do
if (a[i,j] <> b[i,j]) then exit;
Dung:= TRUE;
end;
procedure Game15;
var
k: integer;
d, v: longint;
sx, sy, ex, ey: byte;
begin
Randomize;
ClrScr; d:= 0; v:= 1;
TextBackGround(BLUE);
TextBackGround(BLUE);
TextColor(WHITE);
Init;
gotoxy(5,25); clreol;
write(' Van: ');
79
80
Gi
Vi mi bc b ta cn lu li b gi tr np trc trong on a[0..b-1] ca mng a
ng thi vi v tr hin th trn mn hnh ca cc gi tr trong cc mng tng ng x v
y. Ta s dng s hc ng d cho vic lu tr ny, c th l khi cn np phn t th i trc
ht ta np vo mt bin m z. Sau ta tng phn t a[i mod b] thm k n v v tm n
ct x[i mod b], dng y[i mod b] cp nht li gi tr ny. Cui cng ta chuyn gi tr z vo
a[i mod b]. Ni cch khc ta x l vng m a[0..(b - 1)] theo nguyn tc vng trn. Cc chi
tit x l mn hnh trong trng hp chuyn dng v cun mn hnh khi thao tc dng cui
mn hnh l n gin v c ch r trong chng trnh
(*
Pascal
*)
uses crt;
const
MN = 50;
d = 6; {chieu dai cua moi so}
ML = 12; {so luong tren mot dong}
LIM = d*ML; BL = #32;
W = 500; {kich thuoc toi da cua bang nhay}
var
a: array [0..MN] of integer; {vung dem}
{toa do con tro man hinh}
x, y: array [0..MN] of byte;
{------------------------------Viet n so tren bang nhay bac k buoc b
---------------------------------}
procedure BangNhay(b,k,n: integer);
var
i, j, z, t: integer;
xx, yy: byte; {vi tri con tro}
begin
textattr := 7; clrscr;
writeln('Bang nhay bac ',k,' buoc ',b);
writeln(' gom ',n,' so');
writeln('Bat dau nap day ',n,' so.');
writeln('Sau moi so bam ENTER');
xx:= wherex; yy:= wherey;
for i := 0 to n-1 do
begin
gotoxy(xx,yy); readln(z); {nap 1 so}
if i < b then t := i
else
begin
t:= i MOD b;
for j:= 1 to 5 do
begin {sua lai so truoc do b buoc}
gotoxy(x[t],y[t]); write(BL:d);
gotoxy(x[t],y[t]); write(a[t]);
delay(W);
gotoxy(x[t],y[t]); write(BL:d);
gotoxy(x[t],y[t]); write(a[t]+k);
delay(W);
end;
end;
x[t] := xx; y[t]:= yy;
a[t] := z; xx:= xx + d;
if xx > LIM then
81
82
begin
xx:= 1;
if yy < 24 then inc(yy)
else
begin
gotoxy(1,25); writeln;
for j := 0 to b do dec(y[j]);
end;
end;
end;
gotoxy(xx,yy); write(' KET ');
readln;
end;
BEGIN
BangNhay(3,6,10);
(* Loi giai: -5 -4 -3 -2 -1 0 1 8 9 10 *)
END.
// C#
Cc bi 3.3, 3.4 v 3.5 l n gin. Trong C# c hm ReadKey() cho ra gi tr kiu
ConsoleKeyInfor. Da theo gi tr ny ta c th xc nh phm no c bm. on
trnh di y minh ha kh chi tit vic nhn bit cc phm.
// Minh hoa ham Console.ReadKey()
using System;
using System.Text;
class Sample
{
public static void Main()
{
Test();
}
public static void Test()
{
ConsoleKeyInfo k;
do {
Console.Write("\n Bam phim ESC de thoat: ");
k = Console.ReadKey(true);
char c = k.KeyChar;
Console.Write(c);
if (char.IsLetter(c))
Console.Write(" Chu cai");
else if (char.IsNumber(c))
Console.Write(" Chu so");
else if (char.IsControl(c))
{
Console.Write(" Phim dieu khien ");
switch (k.Key) {
case ConsoleKey.F1: Console.Write(" F1");
break;
83
84
[ 2]
[ 3]
[ 4]
[ 1]
[ 6]
[ 2]
[ 4]
[ 5]
[ 6]
[ 7]
[ 8]
[ 5]
[10]
[ 3]
[ 8]
[ 9]
[10]
[11]
[12]
[ ]
[14]
[ 7]
[11]
[13]
[14]
[15]
[ ]
[ 9]
[13]
[15]
[12]
// C#
using System;
using System.IO;
namespace SangTao1
{
/*------------------------------------------*
Game15
* ------------------------------------------*/
class Game15
{
const int
const int
const int
const int
cot goc
dong goc
giua 2 o tren dong
cach dong
85
86
VeO(dong, cot);
++dong; a[dong, cot] = 0;
VeO(dong, cot);
}
break;
case XUONG://Day quan tren o trong XUONG
if (dong > 0)
{
a[dong,cot]=a[dong-1,cot];
VeO(dong, cot);
--dong; a[dong, cot] = 0;
VeO(dong, cot);
}
break;
case PHAI: // Day quan TRAI o trong sang
if (cot > 0)
{
a[dong, cot]=a[dong,cot-1];
VeO(dong, cot);
--cot; a[dong, cot] = 0;
VeO(dong, cot);
}
break;
case TRAI: // Day quan PHAI o trong sang
if (cot < dd1)
{
a[dong,cot]=a[dong,cot+1];
VeO(dong, cot);
++cot; a[dong, cot] = 0;
VeO(dong, cot);
}
break;
}
} while (k != ESC);
}
static public void Gotoij(int i,int j)
{
Console.SetCursorPosition(scot+dcot*j,
sdong+ddong*i);
}
static public void VeO(int i, int j)
{
int dong = sdong + ddong*i;
int cot = scot + dcot * j;
Console.SetCursorPosition(cot,dong);
Console.Write("
");
Console.SetCursorPosition(cot, dong);
if (a[i,j] == 0)
{
Console.BackgroundColor =
ConsoleColor.Blue;
Console.Write("["+BL+BL+"]");
Console.BackgroundColor =
ConsoleColor.Black;
}
else if (a[i,j] < 10)
Console.Write("[" + BL + a[i,j] + "]");
else Console.Write("[" + a[i,j] + "]");
}
// so sanh hai cau hinh a va b
static public bool Sanhab()
{
for (int i = 0; i < dd; ++i)
for (int j = 0; j < dd; ++j)
if (a[i,j] != b[i,j]) return false;
return true;
}
// Dao ngau nhien maxk lan
static public void DaoNgauNhien(int maxk)
{
Random r = new Random();
for (; Sanhab(); ) // Dao den khi a != b
{
for (int k = 0; k < maxk; ++k)
{
switch (r.Next(4) + 1)
{
case LEN:
// Day quan duoi o trong LEN
if (dong < dd1)
{
a[dong,cot]=a[dong+1,cot];
++dong; a[dong, cot] = 0;
}
break;
case XUONG:
// Day quan tren o trong XUONG
if (dong > 0)
{
a[dong,cot]=a[dong-1,cot];
--dong; a[dong, cot] = 0;
}
break;
case PHAI:
// Day quan TRAI o trong sang
if (cot > 0)
{
a[dong,cot]=a[dong,cot-1];
--cot; a[dong, cot] = 0;
}
break;
case TRAI: // Day quan PHAI o trong sang
if (cot < dd1)
{
a[dong, cot] = a[dong, cot + 1];
++cot; a[dong, cot] = 0;
87
}
break;
} // switch
} // for k
} // for sanh
}
static public void VeBanCo()
{
for (int i = 0; i < dd; ++i)
for (int j = 0; j < dd; ++j)
VeO(i,j);
}
static public void Init()
{
// Khoi tri ban co a.
// Ban co b dung de doi sanh.
int k = 1;
for (int i = 0; i < dd; ++i)
for (int j = 0; j < dd; ++j)
b[i,j] = a[i, j] = k++;
b[dd1,dd1] = a[dd1, dd1] = 0;
dong = dd1; cot = dd1;
DaoNgauNhien(200);
VeBanCo();
}
static public int GetKey()
{
ConsoleKeyInfo k;
k = Console.ReadKey(true);
char c = k.KeyChar;
if (char.IsControl(c))
{
switch (k.Key)
{
case
case
case
case
case
case
}
return 0;
}
} // Game15
} // space
88
89
CHNG 4
T CHC D LIU
Bi 4.1. Cm
Mt cm trong mt biu thc ton hc l on nm gia hai du ng v m
ngoc n (). Vi mi biu thc cho trc hy tch cc cm ca biu thc .
D liu vo: Tp vn bn CUM.INP cha mt dng kiu xu k t (string) l
biu thc cn x l.
D liu ra: Tp vn bn CUM.OUT dng u tin ghi d l s lng cm. Tip
n l d dng, mi dng ghi mt cm c tch t biu thc. Trng hp gp
li c php ghi s 1.
Th d:
CUM.INP
CUM.OUT
x*(a+1)*((b-2)/(c+3))
4
(a+1)
(b-2)
(c+3)
((b-2)/(c+3))
Gi
Gi s xu s cha biu thc cn x l. Ta duyt ln lt t u n cui xu s, vi
mi k t s[i] ta xt hai trng hp:
Trng hp th nht: s[i] l du m ngoc '(': ta ghi nhn i l v tr
xut hin u cm vo mt ngn xp (stack) st:
inc(p); st[p] := i;
trong p l con tr ngn xp. p lun lun tr n ngn, tc l phn t cui
cng ca ngn xp. Th tc ny gi l np vo ngn xp: NapST.
90
(*
Pascal
*)
program Cum;
{$B-}
uses crt;
const
fn = 'CUM.INP'; gn = 'CUM.OUT';
type mb1 = array[1..255] of byte;
91
// C#
using System;
using System.IO;
namespace SangTao1
{
/*---------------------------------------*
Tach cum trong bieu thuc
* -------------------------------------*/
class Cum
{
const string fn = "cum.inp";
const string gn = "cum.out";
static void Main()
{
if (XuLi()) KiemTra();
Console.ReadLine();
}
static public bool XuLi()
{
// Doc du lieu vao string s,
// bo cac dau cach dau va cuoi s
string s = (File.ReadAllText(fn)).Trim();
int[] st = new int[s.Length];//stack
int p = 0; // con tro stack
int sc = 0; // Dem so cum
String ss = ""; // ket qua
for (int i = 0; i < s.Length; ++i)
{
switch (s[i])
{
case '(': st[++p] = i; break;
case ')':
if (p == 0)
{
Console.WriteLine("\nLOI:" +
" Thieu (");
return false;
}
++sc;
for (int j = st[p]; j<=i; ++j)
ss += s[j];
ss += "\n"; // ket dong
--p;
break;
} // switch
} // for
if (p > 0)
{
92
93
Bi 4.2. Bi gp
B bi bao gm n qun, c gn m s t 1 n n. Lc u b bi c chia cho n
ngi, mi ngi nhn 1 qun. Mi lt chi, trng ti chn ngu nhin hai s x v y
trong khong 1..n. Nu c hai ngi khc nhau, mt ngi c trong tay qun bi x v
ngi kia c qun bi y th mt trong hai ngi phi trao ton b s bi ca mnh
cho ngi kia theo nguyn tc sau: mi ngi trong s hai ngi trnh ra mt
qun bi tu chn ca mnh, Ai c qun bi mang m s nh hn s c nhn bi
ca ngi kia. Tr chi kt thc khi c mt ngi cm trong tay c b bi. Bit s
qun bi n v cc qun bi trng ti chn ngu nhin sau m lt chi, hy cho bit
s lng ngi cn c bi trn tay.
D liu vo: Tp vn bn BAIGOP.INP.
- Dng u tin: hai s n v m, trong n l s lng qun bi trong b bi, m
l s ln trng ti chn ngu nhin hai s x v y. Cc qun bi c gn m s
t 1 n n. M s ny c ghi trn qun bi.
- Tip n l m dng, mi dng ghi hai s t nhin x v y do trng ti
cung cp. Cc s trn cng mt dng cch nhau qua du cch.
D liu ra: Hin th trn mn hnh s lng ngi cn c bi trn tay.
Th d:
D liu vo: Kt qu hin th trn ngha: b bi c 10 qun m s ln lt 1,
BAIGOP.INP
2,, 10 v c 10 ngi chi. Su ln trng ti
mn hnh
chn ngu nhin cc cp s (x, y) l (2, 5),
10 6
5
(3, 3), (4, 7), (1, 5), (2, 8) v (9, 3). Cui vn
2 5
chi cn li 5 ngi c bi trn tay: {1, 2, 5, 8},
3 3
{3, 9}, {4, 7}, {6}, {10}.
4 7
1 5
2 8
9 3
Thut ton
y l bi ton c nhiu ng dng hu hiu nn bn c cn tm hiu k v c gng
ci t cho nhun nhuyn. Nh sau ny s thy, nhiu thut ton x l th nh tm
94
cy khung, xc nh thnh phn lin thng, xc nh chu trnh s phi vn dng cch
t chc d liu tng t nh thut ton s trnh by di y.
Bi ny i hi t chc cc tp qun bi sao cho thc hin nhanh nht cc thao tc
sau y:
Find(x): cho bit tn ca tp cha phn t x.
Union(x, y): hp tp cha x vi tp cha y.
Mi tp l nhm cc qun bi c trong tay mt ngi chi. Nh vy mi tp l mt
tp con ca b bi {1, 2,, n}. Ta gi b bi l tp ch hay tp nn. Do tnh cht ca
tr chi, ta c hai nhn xt quan trng sau y:
1. Hp ca tt c cc tp con (mi tp con ny do mt ngi ang chi qun
l) ng bng tp ch.
2. Hai tp con khc nhau khng giao nhau: ti mi thi im ca cuc chi,
mi qun bi nm trong tay ng mt ngi.
H cc tp con tha hai tnh cht ni trn c gi l mt phn hoch ca tp ch.
Cc thao tc ni trn phc v trc tip cho vic t chc tr chi theo s sau:
Khi tr:
for i:= 1 to n do
begin
Trng ti sinh ngu nhin hai s x v y
trong khong 1..n:
Hp tp cha x vi tp cha y: Union(x,y);
end;
thc hin th tc Union(x,y) trc ht ta cn bit qun bi x v qun bi y
ang trong tay ai? Sau ta cn bit ngi gi qun bi x (hoc y) c qun bi nh
nht l g? Qun bi nh nht c xc nh trong ton b cc qun bi m ngi c
trong tay. y chnh l im d nhm ln. Th d, ngi chi A ang gi trong tay cc
qun bi 3, 4 v 7, A = {3, 4, 7}; ngi chi B ang gi cc qun bi 2, 5, 9 v 11, B =
{2, 5, 9, 11}. Cc s gch chn l s hiu ca qun bi nh nht trong tay mi ngi.
Nu x = 9 v y = 7 th A (ang gi qun y = 7) v B (ang gi qun x = 9) s phi u
vi nhau. V trong tay A c qun nh nht l 3 v trong tay B c qun nh nht l 2 nn
A s phi np bi cho B v ra khi cuc chi. Ta c, B = {2, 3, 4, 5, 7, 9, 11}. Ta kt
hp vic xc nh qun bi x trong tay ai v ngi c qun bi nh nht l bao nhiu
lm mt xy dng hm Find(x). C th l hm Find(x) s cho ta qun bi nh
nht c trong tay ngi gi qun bi x. Trong th d trn ta c:
Find(x) = Find(9) = 2 v Find(y) = Find(7) = 3
Lu rng hm Find(x) khng ch r ai l ngi ang gi qun bi x m cho
bit qun bi c s hiu nh nht c trong tay ngi ang gi qun bi x, ngha l
Find(9)=2 ch khng phi Find(9) = B. gii quyt s khc bit ny ta hy
chn phn t c s hiu nh nht trong tp cc qun bi c trong tay mt ngi lm
phn t i din ca tp . Ta cng ng nht phn t i din vi m s ca ngi
gi tp qun bi. Theo quy nh ny th biu thc Find(9)=2 c th c hiu theo
mt trong hai ngha tng ng nh sau:
Ngi s 2 ang gi qun bi 9.
Tp s 2 cha phn t 9.
T chc hm Find nh trn c li l sau khi gi i:=Find(x) v j:=Find(y) ta
xc nh ngay c ai phi np bi cho ai. Nu i < j th j phi np bi cho i, ngc
95
Nu i = j th khng lm g.
K thut ni trn c gi l hp cc tp con ri nhau.
Ta dng mt mng nguyn a th hin tt c cc tp. Khi hai tp A v B ni trn
c th hin trong a nh sau:
a[3] = 3; a[4] = 3; a[7] = 3;
{tp A: phn t i din l 3, cc phn t 3, 4 v 7 u tr n 3}
a[2] = 2; a[5] = 2; a[9] = 2; a[11] = 2;
{tp B: phn t i din l 2, cc phn t 2, 5, 9 v 11 u tr n 2}
(1)
(2)
(3)
(4)
(5)
2
(B)
3
(A)
3
(A)
2
(B)
(6)
(7)
(8)
3
(A)
(9)
(10)
(11)
2
(B)
(12)
(13)
(14)
(15)
2
(B)
(2)
(3)
(4)
(5)
(6)
(7)
3
(8)
(9)
2
(10)
(11)
(12)
(13)
(14)
(15)
96
97
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(13)
(14)
(15)
10
12
p s: ba tp.
Tp vi i din 1: {1, 8, 14}.
Tp vi i din 2: {2, 3, 4, 5, 7, 9, 11, 13}.
Tp vi i din 6: {6, 10, 12, 15}.
(*
Pascal
*)
(*----------------------------------BAI GOP
------------------------------------*)
program BaiGop;
uses crt;
const
MN = 5000;
fn = 'BAIGOP.INP';
var
a: array[1..MN] of integer;
c,n,m: integer;
{c: dem so tap
n: so quan bai = so nguoi choi
m: so lan trong tai sinh 2 so}
f: text;
{---------------------------------Xac dinh tap chua phan tu x
-----------------------------------}
function Find(x: integer): integer;
begin
while (x <> a[x]) do x:= a[x];
Find := x;
end;
{------------------------------------Hop cua tap chua x voi tap chua y.
Union = 1: co hop nhat
Union = 0: khong hop nhat vi x va y
thuoc cung 1 tap
--------------------------------------}
function Union(x,y: integer): integer;
begin
Union := 0;
x := Find(x);
y := Find(y);
if x = y then exit
else if x < y then a[y] := x
else a[x] := y;
Union := 1;
end;
{----------------------------------------------Dem so luong tap con roi nhau (so nguoi choi)
-----------------------------------------------}
function Dem: integer;
var d,i: integer;
begin
d := 0;
for i := 1 to n do
if a[i] = i then inc(d);
Dem:= d;
end;
procedure BaiGop;
var i,j,k,x,y: integer;
begin
assign(f,fn); reset(f);
readln(f,n,m);
{n so quan bai; m so lan chon x,y}
c := n; {c: so nguoi choi}
if (n < 1) or (n > MN) then exit;
for i := 1 to n do a[i] := i;
for i := 1 to m do
begin
readln(f,x,y);
c := c-Union(x,y);
end;
writeln(c);
close(f);
end;
BEGIN
BaiGop;
END.
// C#
using System;
using System.IO;
namespace SangTao1
/*-------------------------------------*
Bai gop
* -------------------------------------*/
class BaiGop
{
const string fn = "baigop.inp";
static int[] a; // quan li cac tap roi nhau
static int n = 0; // so quan bai
static int m = 0;// so lan trong tai
// chon 2 quan bai
static void Main()
{
98
99
Run();
Console.ReadLine();
} // Main
// Xac dinh tap chua phan tu x
static int Find(int x) t vit
static int Union(int x, int y) t vit
static void Run()
{
int [] b = ReadInput();
n = b[0];
m = b[1];
a = new int[n + 1];
for (int i = 1; i <= n; ++i)
a[i] = i;
int j = 2, d = n;
for (int i = 1; i <= m; ++i)
{
d -= Union(b[j], b[j+1]);
j += 2;
}
Console.WriteLine("\n " + d + "\n");
}
static int[] ReadInput()
{
char[] cc = new char[]
{ ' ', '\n', '\t', '\r'};
string[] ss = (File.ReadAllText(fn)).
Split(cc,StringSplitOptions.
RemoveEmptyEntries);
return Array.ConvertAll(ss,
new Converter<string, int>(int.Parse));
}
} // BaiGop
} // SangTao1
Bi 4.3. Chui ht
Trong mt tp vn bn tn CHUOI.DAT c biu din mt chui ht, mi ht
c th nhn mt trong s cc mu m s t 1 n 30.
Lp trnh thc hin cc vic sau:
a) c chui ht t tp vo mng nguyn dng a.
b) Hin th s mu c trong chui.
c) Tm mt im ct chui ri cng thng ra sao cho tng s cc ht cng
mu hai u l ln nht.
Chui c th hin trong tp di dng hnh thoi, dng u tin v dng cui
cng mi dng c mt ht.
Mi dng cn li c hai ht (xem hnh).
Cc ht ca chui c nh s bt u t ht trn cng v theo chiu kim
ng h.
CHUOI.DAT
100
4
4
1
5
5
5
S mu trong chui: 5
Ct gia ht th 7 v th 8, tng s ln nht l 7.
7
4
8
8
8
8
Chui ht
Thut ton
Khung chng trnh c phc tho nh sau:
procedure run;
var i: integer;
begin
c d liu;
Tnh v thng bo s mu
X l tm im ct;
Thng bo im ct
end;
c chui t tp vo mng a ta dng thm mt mng ph b c cng cu trc
nh mng a. Mng b s cha cc ht na tri chui, trong khi mng a cha cc ht
na phi. Lc u, do ch c 1 ht ti dng u tin nn ta c ht vo a[1]. Ti cc
dng tip theo, mi dng n = 2, ta c s hiu mu ca 2 ht, ht tri vo b[n] v ht
phi vo a[n]. Du hiu kt thc chui l 1 ht. Ht ny c c vo b[n]. Ta
rng, theo cu trc ca chui ht th s ht trong chui lun lun l mt s chn.
Th d di y minh ho giai on u ca th tc c d liu. Khi kt thc giai
on ny ta thu c n = 7 v na phi ca chui ht (s c gch di) c ghi trong
a[1..(n 1)], na tri c ghi trong b[2..n]. Tng s ht trong chui khi s l
2*(n 1).
CHUOI.DAT
4
a[1]
b[2] 4
7 a[2]
b[3] 1
4 a[3]
b[4] 5
8 a[4]
b[5] 5
8 a[5]
b[6] 5
8 a[6]
b[7]
c d liu ca chui ht vo
hai mng a v b
a[1..6]=(4,7,4,8,8,8)
b[2..7]=(4,1,5,5,5,8)
Sau khi c xong ta duyt ngc mng b ni na tri ca chui ht vo sau na
phi a.
101
102
103
104
(*
Pascal
*)
(*-------------------CHUOI HAT
---------------------*)
program Chuoi;
{$B-}
uses crt;
const
MN = 500; {So luong hat toi da trong chuoi}
MC = 30; {So luong mau}
fn = 'CHUOI.DAT';
BL = #32;
var
a,b,len: array[0..MN] of byte;
n: integer; {So luong phan tu thuc co trong chuoi hat}
DiemCat: integer; {diem cat}
Lmax: integer; {Chieu dai toi da}
(*----------------------------------Doc du lieu tu tep CHUOI.DAT ghi
vao mang a
------------------------------------*)
procedure Doc;
var
f: text;
i: integer;
begin
assign(f,fn);
reset(f);
n:= 1;
read(f,a[1]);
while not SeekEof(f) do
begin
inc(n);
read(f,b[n]);
if not SeekEof(f) then read(f,a[n]);
end;
for i:=0 to n-2 do a[n+i]:= b[n-i];
n:= 2*(n-1);
close(f);
end;
(*------------------------------------Hien thi chuoi tren man hinh
de kiem tra ket qua doc
105
--------------------------------------*)
procedure Xem;
var i: integer;
begin
writeln;
writeln('Tong so hat: ',n);
for i:= 1 to n do
write(a[i],bl);
end;
(*----------------------------------Dem so mau trong chuoi
------------------------------------*)
function Dem: integer;
var i,d: integer;
begin
d:=0;
fillchar(b,sizeof(b),0);
for i:= 1 to n do
if b[a[i]] = 0 then
begin
inc(d);
b[a[i]]:=1;
end;
Dem:= d;
end;
procedure xuly;
var i,sdc: integer; {sdc: so diem cat}
begin
sdc:=0;
if a[1]<>a[n] then
begin
sdc:=1;
b[sdc]:=1;
end;
for i:=1 to n-1 do
if a[i] <> a[i+1] then
begin
inc(sdc);
b[sdc]:=i+1;
end;
if sdc=0 then
begin
DiemCat:=0;
Lmax:=n;
exit;
end;
{xu li diem cat dau}
Lmax:= (b[1]+(n-b[sdc]))+(b[2]-b[1]);
DiemCat:=b[1];
{xu li diem cat cuoi}
if (b[1]+(n-b[sdc]))+(b[sdc]-b[sdc-1]) > Lmax
then
begin
106
Lmax:= (b[1]+(n-b[sdc]))+(b[sdc]-b[sdc-1]);
DiemCat:=b[sdc];
end;
{xu li cac diem cat giua}
for i:=2 to sdc-1 do
if b[i+1]-b[i-1] > Lmax then
begin
Lmax:= b[i+1]-b[i-1];
DiemCat:=b[i];
end;
end;
procedure run;
var i: integer;
begin
Doc; Xem; writeln;
writeln('So mau trong chuoi: ',Dem);
xuly;
writeln;
if DiemCat=0 then
writeln(' Chuoi dong mau, cat tai diem tuy y')
else
begin
if DiemCat = 1 then i :=n
else i:=DiemCat-1;
writeln('Cat giua hat ',i,
' va hat ',DiemCat);
end;
writeln(' Chieu dai max: ',Lmax);
readln;
end;
BEGIN
run;
END.
D liu kim th
CHUOI.DAT
4
4
7
1
4
5
8
5
8
5
8
8
// C#
using System;
using System.IO;
namespace SangTao1
{
class ChuoiHat
{
Kt qu d kin
Ct gia ht: 7 v 8
Chiu di max: 7
107
108
Gi
Chng trnh gii thiu hai th tc sp mng l MinSort v QuickSort. Theo
phng php MinSort vi mi i ta tm phn t nh nht a[j] trong on a[i..n] sau ta
i ch phn t ny vi phn t a[i]. Nh vy mng c chia thnh hai on: on
tri, a[1..i] c sp tng, cn on phi a[i + 1..n] cha x l. Mi bc ta thu hp
on phi cho n khi cn mt phn t l xong.
Theo phng php QuickSort ta ly mt phn t x nm gia on mng cn sp
lm mu ri chia mng thnh hai on. on tri a[1..i] bao gm cc gi tr khng ln
hn x v on phi a[j..n] bao gm cc gi tr khng nh thua x. Tip n ta lp li th
tc ny vi hai on thu c nu chng cha nhiu hn mt phn t.
(*
Pascal
*)
109
var i: integer;
begin
for i:= d+1 to c do
if a[i] < a[d] then d:= i;
Min:= d;
end;
procedure MinSort;
var i, j, y: integer;
begin
for i:= 1 to n-1 do
begin
j:= Min(i,n);
{doi cho a[i] va a[j]}
y:= a[i];
a[i]:= a[j];
a[j]:= y;
end;
end;
(*---------------------------------Ghi tep, moi dong khong qua 20 so
-----------------------------------*)
procedure Ghi;
var i: integer;
begin
assign(f,fn); rewrite(f);
writeln(f,n);
for i:= 1 to n do
begin
write(f,a[i]:5);
if i mod 20 = 0 then writeln(f);
end;
close(f);
end;
procedure TestQuickSort;
begin
Init(MN);
QuickSort(1,n);
Ghi;
write('Fini Quick Sort'); readln;
end;
procedure TestMinSort;
begin
Init(MN);
MinSort;
Ghi;
write('Fini Min Sort'); readln;
end;
BEGIN
TestQuickSort;
{TestMinSort;}
END.
//
C#
110
111
using System;
using System.IO;
namespace SangTao1
{
/*--------------------------------------*
Sinh du lieu
*
Sap tang
*
Ghi file
* -------------------------------------*/
class SapTang
{
const int mn = 50000;
const string fn = "SapTang.dat";
static int[] a = new int[mn];
static int n = 0; // so phan tu trong input file
static void Main()
{
Run(150);
Console.ReadLine();
} // Main
static void Run(int nn) // sinh nn phan tu
{
n = nn;
Console.Write("\n Sinh ngau nhien " + n);
Console.WriteLine("\n phan tu cho mang
a[0.." + (n - 1) +
"]");
Gen();
Console.WriteLine("\n Quik Sort...");
QSort(0, n - 1);
Console.WriteLine("\n Ghi file " + fn + "...");
Ghi();
Console.WriteLine("\n Kiem tra lai file " +
fn + "\n\n");
ShowFile();
}
/*-----------------------------* Sinh ngau nhien n so nguyen
* cho mang a[0..n-1]
* -----------------------------*/
static void Gen()
{
Random r = new Random();
for (int i = 0; i < n; ++i) a[i] = r.Next(100);
}
/*-----------------------------* Giai thuat sap (tang) nhanh
* Quick Sort (Hoare T.)
* -----------------------------*/
static void QSort(int d, int c)
{
112
int i = d;
int j = c;
int m = a[(i + j) / 2];
int t;
while (i <= j)
{
while (a[i] < m) ++i;
while (m < a[j]) --j;
if (i <= j)
{
t = a[i]; a[i] = a[j]; a[j] = t;
++i; --j;
}
}
if (d < j) QSort(d, j);
if (i < c) QSort(i, c);
}
static void MinSort()
{
int i = 0;
int j = 0;
int t = 0;
for (i = 0; i < n;
for (j = i + 1;
if (a[j] <
{ t = a[i]; a[i] =
++i)
j < n; ++j)
a[i])
a[j]; a[j] = t;}
}
/*---------------------------------* Ghi du lieu vao file SapTang.Dat
* ---------------------------------*/
static void Ghi()
{
StreamWriter f = File.CreateText(fn);
f.WriteLine(n);
for (int i = 0; i < n; ++i)
f.Write(a[i] + ((i % 10 == 9) ? "\n" : " "));
f.Close();
}
/*------------------------------* Doc lai du lieu tu file
* SapTang.dat de kiem tra
* ------------------------------*/
static void ShowFile()
{
Console.WriteLine(File.ReadAllText(fn));
}
} // class
} // SangTao1
113
= 0, 1,, N - 1. Nh vy xu th cp vi i = 0 s trng vi xu mu S. Gi s
ta sp tng N xu thu c theo trt t t in. Hy tm xu th k trong dy.
Tn chng trnh: abc.pas.
D liu vo: tp vn bn abc.inp c cu trc nh sau:
- Dng th nht cha hai s t nhin N v k cch nhau qua du cch,
6 N 500, 1 k N. N cho bit chiu di xu S, k cho bit v tr ca xu
th cp trong dy c sp tng theo th t t in.
- Dng th hai: xu mu S.
D liu ra: tp vn bn abc.out gm mt dng cha xu th k trong dy
c sp.
Th d:
abc.inp
abc.out
6 3
dabdec
cdabde
Bi gii
Ta gi xu s ban u l xu mu, cc xu c sinh ra bi php quay l xu th
cp. rng cc xu mu cng l mt xu th cp ng vi php quay 0 v tr. Ta c
th nhn c xu th cp th i bng cch duyt xu mu theo vng trn k t v tr th
i v cui, n v tr th n. Sau duyt tip tc t v tr th 1 n v tr th i - 1. Ta k
hiu xu th cp th i l [i]. Th d, nu xu mu s = 'dabdec' th xu th cp th
2 s l [2] = 'abdecd'. tm xu th k trong dy c sp, trc ht ta cn sp
tng cc xu theo trt t t in sau ly xu th k trong dy c sp lm kt qu.
sp tng c cc xu ny m khng phi sinh ra cc xu mi ta dng mt mng
ph id gi l mng ch dn. Trc khi sp ta gn id[i]:= i. Sau khi sp th id[i] s cho
bit ti v tr th i trong dy c sp l xu th cp no. Trong th d trn, id[3] = 6 l
xu th cp [6]. Gi tr 3 cho bit cn tm xu th k = 3 trong dy sp tng cc xu th
cp. Gi tr 6 cho bit xu cn tm l xu th 6 trong dy cc xu th cp c sinh ra
lc u, tc l lc cha sp.
Xu th cp
Sp tng
id[i] = ?
[1] = S
dabdec
[2]
[2]
abdecd
[3]
[3]
bdecda
[6]
[4]
decdab
[1]
[5]
ecdabd
[4]
[6]
cdabde
[5]
Sp ch dn cc xu th cp
Thut ton QuickSort sp nhanh cc xu th cp do Hoare xut c phc tp
N.log2N c trnh by nh sau:
Init: for i:=1 to n do id[i]:=i;
procedure idquicksort(d,c: integer);
var i, j, m, y: integer;
begin
i:=d;
j:=c;
114
(*
Pascal
*)
115
n,k: integer;
(*--------------------------------------------Doc du lieu:
n: chieu dai xau s,
k: vi tri xau thu cap trong day da sap
----------------------------------------------*)
procedure Doc;
var i: integer;
begin
assign(f,fn); reset(f);
readln(f,n,k);
for i:=1 to n do read(f,s[i]);
close(f);
end;
(*---------------------------------------So sanh 2 xau thu cap [i] va [j].
Sanh(i,j)
= 0: neu [i] = [j]
= -1: neu [i] < [j]
= 1 neu [i] > [j]
----------------------------------------*)
function Sanh(i,j: integer): integer;
var k: integer;
begin
for k:=1 to n do
begin
if s[i] <> s[j] then
begin
if s[i] < s[j] then Sanh:=-1
else Sanh:=1;
exit;
end;
if i=n then i:=1 else inc(i);
if j=n then j:=1 else inc(j);
end;
Sanh:=0;
end;
(*------------------------------------Tim phan tu thu k
---------------------------------------*)
function Find(k: integer):integer;
var d, c, i, j, m, y: integer;
begin
d:=1 ;
c:=n;
while d <= c do
begin
i:=d;
j:=c;
m:=id[(i+j) div 2]; {phan tu giua}
while i <= j do
begin
while Sanh(id[i],m)<0 do inc(i); {doan trai}
116
// C#
using System;
using System.IO;
namespace SangTao1
{
/*---------------------------------------*
Tim xau mau thu k voi do phuc tap 2N
* -------------------------------------*/
class abc
{
const int mn = 500;
const string fn = "abc.inp";
117
118
119
120
}
}
if (d < j) IdQSort(d, i);
if (i < c) IdQSort(i, c);
}
/*------------------------------* Kiem tra lai bang cach dung
* thuat toan QSort theo chi dan
* ------------------------------*/
static void Test()
{
Console.WriteLine("\n Xau mau: " + s);
for (int i = 0; i < n; ++i) id[i] = i;
IdQSort(0, n - 1);
Console.WriteLine("\n Day sap tang: \n");
for (int i = 0; i < n; ++i)
{
Console.Write((i + 1) + ". ");
PrintLine(id[i]);
}
Console.WriteLine();
Console.WriteLine("\n Xau thu " + k);
PrintLine(id[k-1]);
Console.WriteLine("\n Xau ghi trong file " + gn);
Console.WriteLine(File.ReadAllText(gn));
}
} // class
} // SangTao1
Bi 4.6. Xu mu
Mt tp vn bn f c tn STRINGS.INP cha cc xu k t, mi dng ghi mt
xu c chiu di ti a 250 k t. Xu u tin c gi l xu mu s. Lp
trnh:
c xu mu s t tp f, ghi vo tp vn bn g c tn STRINGS.OUT. Sau
c tng xu x cn li ca f, vi mi xu x cn ghi vo g cc thng tin sau:
ni dung xu x;
hai s v v d cch nhau qua du cch, trong v l v tr xut hin v d
l chiu di ln nht ca khc u ca x trong xu mu s. Nu v nghim
th ghi -1 0.
Th d:
STRINGS.INP
cabxabcdab
abcd
cdaeh
STRINGS.OUT
cabxabcdab
abcd
5 4
cdaeh
7 3
Thut ton
Vi mi xu k t w ta k hiu w[i..j], i j, v gi l on, l xu gm dy k t lin
tip t w[i] n w[j] trong xu w. Th d, nu w = 'cabxabcdab' th w[5..8] = 'abcd'. Gi
121
id[i]
Hu t
Xu
S[9..10]
ab
S[5..10]
abcdab
S[2..10]
abxabcdab
10
S[10..10]
S[6..10]
bcdab
S[3..10]
bxabcdab
S[1..10]
cabxabcdab
S[7..10]
cdab
S[8..10]
dab
10
S[4..10]
xabcdab
Sp tng theo ch dn cc hu t ca xu
s[1..10] = 'cabxabcdab'
Vic cn li l so snh xu x vi cc hu t s[i..j] tm khc u chung di nht
gia chng. Th d, vi x[1..4]='abcd' th khc u chung di nht tm c vi
hu t s[5..10] do id[2] tr ti. V tr v tm c s l 5 v chiu di ln nht d s l 4.
Phn chnh ca chng trnh s nh sau:
procedure Run;
begin
...
n:= length(s);
122
123
(*
Pascal
*)
function min(a,b:integer):integer;
begin
if a<=b then min:=a
else min:=b;
end;
(*------------------------------Tim xuat hien cua x[1] trong day da sap cac hau to
-------------------------------*)
function BinSearch:integer;
var
d,c,m: integer;
begin
d:=1;
c:=n;
repeat
m:=(d+c) div 2;
if x[1]>s[id[m]] then d:=m+1
else c:=m;
until d=c;
if x[1]<>s[id[d]] then Binsearch:=0
else BinSearch:=d;
end;
(*-------------------------------------so sanh 2 hau to trong s:
s[i..n] va s[j..n]
---------------------------------------*)
function sanh(i,j:integer):integer;
var k:integer;
begin
for k:=0 to min(n-i,n-j) do
if s[i+k]<>s[j+k] then
begin
if s[i+k]<s[j+k] then sanh:=-1
else sanh:=1;
exit;
end;
if i=j then sanh:=0
else if i<j then sanh:=1
else sanh:=-1;
end;
(*------------------------------------Quick sort cac hau to theo chi dan
-------------------------------------*)
procedure IdQuickSort(d,c: integer);
var i,j,m,t: integer;
begin
i:=d; {dau}
j:=c; {cuoi}
m:=id[(i+j) div 2]; {phan tu giua}
while i<=j do
begin
124
125
126
var i:integer;
begin
assign(f,fn);
reset(f);
assign(g,gn);
rewrite(g);
readln(f, s);
writeln(g,s);
n:= length(s);
for i:=1 to n do id[i]:=i;
IdQuickSort(1,n);
while not seekeof(f) do
begin
readln(f,x);
writeln(g,x);
Tim;
writeln(g,v,BL,d);
end;
close(f);
close(g);
end;
BEGIN
Run;
END.
D liu kim th
STRINGS.INP
cabxabcdab
abcd
cdaeh
//
Kt qu d kin
STRINGS.OUT
cabxabcdab
abcd
5 4
cdaeh
7 3
C#
using System;
using System.IO;
namespace SangTao1
{
/*-----------------------*
Xau mau
* ----------------------*/
class Strings
{
const string fn = "strings.inp";
const string gn = "strings.out";
static string s; // xau mau
static string x; // xau can xu ly
127
128
f.Close(); g.Close();
}
static void Find()
{
v = BinSearch(x[0]);// hau to co ki tu dau la x[0]
d = 0;
if (v < 0) return;
for (int i = v; i < n; ++i)
{
int j = id[i];
if (s[j] != x[0]) return;
int k = ComLen(x, j);
if (d < k) { v = j + 1; d = k;}
}
}
// MaxLen khuc dau cua x va hau to s[j...
static int ComLen(string x, int j)
{
int minlen = Min(x.Length, n - j);
for (int i = 0; i < minlen; ++i)
if (x[i] != s[j + i]) return i;
return minlen;
}
static int Min(int a, int b)
{ return (a < b) ? a : b;}
static int BinSearch(char c)
{
int i = 0;
int j = n - 1;
int m = 0;
while (i < j)
{
m = (i + j) / 2;
if (s[id[m]] < c) i = m + 1;
else j = m;
}
return (s[id[i]] == c) ? i : -1;
}
// Hien thi day duoc sap cac hau to
// cua s de kiem tra
static void SPrint()
{
Console.WriteLine("\n Cac hau to sap tang: \n");
for (int i = 0; i < n; ++i)
Console.WriteLine(s.Substring(id[i], n - id[i]));
}
static void IdQSort(int d, int c)
{
int i = d;
int j = c;
int m = id[(i + j) / 2];
int t = 0;
while (i <= j)
{
while (Sanh(id[i], m) < 0) ++i;
while (Sanh(m, id[j]) < 0) --j;
if (i <= j)
{
t = id[i]; id[i] = id[j]; id[j] = t;
++i; --j;
}
}
if (d < j) IdQSort(d, j);
if (i < c) IdQSort(i, c);
}
static int Sanh(int x, int y)
{
int ix = 0;
int iy = 0;
for (int i = 0; i < n; ++i)
{
ix = (x + i) % n;
iy = (y + i) % n;
if (s[ix] != s[iy])
return (s[ix] < s[iy]) ? -1 : 1;
}
return 0;
}
} // Strings
} // SangTao1
CHNG 5
129
130
Thut ton
Gi s ta c ba bi ht vi s pht ln lt nh sau:
M s bi ht
131
( , , )
(7) + (7 + 2) + (7 + 2 + 3) = 28 pht
( , , )
(7) + (7 + 3) + (7 + 3 + 2) = 29 pht
( , , )
(2) + (2 + 7) + (2 + 7 + 3) = 23 pht
( , , )
( , , )
(3) + (3 + 7) + (3 + 7 + 2) = 25 pht
( , , )
(3) + (3 + 2) + (3 + 2 + 7) = 20 pht
(*
Pascal
*)
(*---------------------BangNhac.pas
-----------------------*)
program BangNhac;
uses crt;
const
MN = 200; BL = #32; {dau cach}
fn = 'Bangnhac.inp'; gn = 'Bangnhac.out';
var
a,id: array[1..MN] of integer;
f, g: text;
n: integer;
{-----------------------------------Doc du lieu tu input file vao mang a
-------------------------------------}
procedure Doc;
var i,k: integer;
begin
assign(f,fn); reset(f); read(f,n);
for i := 1 to n do read(f,a[i]);
close(f);
end;
{--------------------------------Khoi tri mang chi dan id
quan li sap tang theo chi dan
----------------------------------}
procedure InitID;
var i: integer;
begin
for i := 1 to n do id[i] := i;
end;
{--------------------------------Sap tang theo chi dan
----------------------------------}
// C#
using System;
using System.IO;
namespace SangTao1
{
/*------------------------------------*
Bang nhac
* -----------------------------------*/
class BangNhac
{
const string fn = "BangNhac.inp";
132
133
134
b = new Bang[n];
for (int i = 1; i <= n; ++i)
b[i-1] = new Bang(a[i],i);
}
public struct Bang
{
public int len;// thoi luong
public int id; // so hieu 1,2,...
public Bang(int t, int nn)
{ len = t; id = nn;}
}
} // BangNhac
} // SangTao1
Bi 5.2. Xp vic
C N cng vic cn thc hin trn mt my tnh, mi vic i hi ng 1 gi
my. Vi mi vic ta bit thi hn phi np kt qu thc hin sau khi hon thnh
vic v tin thng thu c nu np kt qu trc hoc ng thi im quy
nh. Ch c mt my tnh trong tay, hy lp lch thc hin N cng vic trn
my tnh sao cho tng s tin thng thu c l ln nht v thi gian hot ng
ca my l nh nht. Gi thit rng my c khi ng vo u ca, thi im
t = 0 v ch tt my sau khi hon thnh N cng vic.
D liu vo: tp vn bn viec.inp:
Dng u tin l s N.
N dng tip theo: mi vic c m t bng hai s t nhin, s th nht l thi
hn giao np, s th hai l tin thng. Cc s cch nhau bi du cch.
Th d:
viec.inp
4
1 15
3 10
5 100
1 27
viec.out
4
2
3
1
137
ngha:
- Gi th 1 thc hin vic 4 v np ng hn nn c
thng 27;
- Gi th 2 thc hin vic 2 v np trc hn nn c
thng 10;
- Gi th 3 thc hin vic 3 v np trc hn nn c
135
thng 100;
- Gi th 4 thc hin vic 1;
- Tng tin thng thu c do hon thnh ng hn
ba vic 4, 2 v 3 l 27 + 10 + 100 = 137.
Thut ton
Ta u tin cho nhng vic c tin thng cao, do ta sp cc vic gim dn theo
tin thng. Vi mi vic k ta bit thi hn giao np vic l h = t[k]. Ta xt trc
thi gian b. Nu gi h trn trc bn do vic khc th ta tm t thi im h tr v
trc mt thi im c th thc hin c vic k . Nu tm c mt thi im m nh
vy, ta nh du bng m s ca vic trn trc thi gian b, b[m]:= k. Sau khi xp
vic xong, c th trn trc thi gian cn nhng thi im ri, ta dn cc vic xp v
pha trc nhm thu c mt lch lm vic tr mt, tc l khng c gi trng. Cui
cng ta xp tip nhng vic trc xt nhng khng xp c. y l nhng vic
phi lm nhng khng th np ng hn nn s khng c tin thng. Vi th d
cho, N = 4, thi hn giao np t = (1, 3, 5, 1) v tin thng a = (15, 10, 100, 27) ta
tnh ton nh sau:
- Khi tr: trc thi gian vi 5 thi im ng vi Tmax = 5 l th im mun
nht phi np kt qu, Tmax = max { thi hn giao np }, b = (0, 0, 0, 0,0).
- Chn vic 3 c tin thng ln nht l 100. Xp vic 3 vi thi hn t[3] = 5 vo
h: h[5] = 3. Ta thu c h = (0, 0, 0, 0, 3).
- Chn tip vic 4 c tin thng 27. Xp vic 4 vi thi hn t[4] = 1 vo h: h[1]
= 4. Ta thu c h = (4, 0, 0, 0, 3).
- Chn tip vic 1 c tin thng 15. Xp vic 1 vi thi hn t[1] = 1 vo h:
Khng xp c v t thi im 1 tr v trc trc thi gian h[1..1] kn. Ta
thu c h = (4, 0, 0, 0, 3).
- Chn nt vic 2 c tin thng 10. Xp vic 2 vi thi hn t[2] = 3 vo h:
h[3] = 2.
- Ta thu c h = (4, 0, 2, 0, 3).
- Dn vic trn trc thi gian h, ta thu c h = (4, 2, 3, 0, 0).
- Xp nt vic phi lm m khng c thng, ta thu c h = (4, 2, 3, 1).
- Ca lm vic ko di ng N = 4 gi.
- Nu khng mun sp gim mng tin thng a theo ch dn ta c th sp song
song a v id nh m t trong chng trnh.
Trong chng trnh di y ta s dng mng id vi hai mc ch: id[i] = v > 0
cho bit vic v ng th i trong dy c sp gim theo gi tr tin thng v vic v
cha c xp. id[i] = v < 0 cho bit vic v xp xong trong ln duyt u tin.
(*
Pascal
*)
136
137
// C#
using System;
using System.IO;
namespace SangTao1
{
/*-----------------------*
Xep viec
* ----------------------*/
class XepViec
{
const int mn = 280;
const string fn = "Viec.inp";
const string gn = "Viec.out";
static public Viec [] v; // cac viec
static public int n = 0; // so luong viec
static public int tong = 0;
static public int[] h;
static public int k = 0;
static void Main()
{
Doc(); QSort(0, n-1);
Xep(); Ghi(); Test();
Console.ReadLine();
} // Main
static void Xep()
{
// Tim Tmax
138
int tmax = 0;
for (int i = 0; i < n; ++i)
if (v[i].t > tmax) tmax = v[i].t;
int tt = tmax + n + 1;
h = new int[tt];
// Khoi tri cho h
for (int i = 0; i < tt; ++i) h[i] = 0;
tong = 0;
for (int i = 0; i < n; ++i)
{
int td = v[i].t;
while (h[td] > 0) --td;
if (td == 0)
h[++tmax] = v[i].id; //viec ko thg
else
{
h[td] = v[i].id;
tong += v[i].thuong;
}
}
// Dich cac viec len phia truoc
k = 0;
for (k = 1; k <= tmax; ++k)
if (h[k] == 0) break;
for (int i = k + 1; i <= tmax; ++i)
if (h[i] > 0)
h[k++] = h[i];
}
static void Ghi() // Ghi file
{
StreamWriter g = File.CreateText(gn);
for (int i = 1; i < k; ++i)
g.WriteLine(h[i]);
g.WriteLine(tong); g.Close();
}
// Sap cac viec giam theo tien thuong
static void QSort(int d, int c)
{
int i = d;
int j = c;
int m = v[(d + c) / 2].thuong;
Viec t = new Viec(0, 0, 0);
while (i <= j)
{
while (v[i].thuong > m) ++i;
while (m > v[j].thuong) --j;
139
140
if (i <= j)
{
t = v[i]; v[i] = v[j]; v[j] = t;
++i; --j;
}
}
if (d < j) QSort(d, j);
if (i < c) QSort(i, c);
}
// Doc lai file gn de kiem tra ket qua
static void Test() t vit
static void Doc()
{
int [] a = Array.ConvertAll(
(File.ReadAllText(fn)).Split(
new char[] { '\n', ' ', '\t', '\0', '\r' },
StringSplitOptions.RemoveEmptyEntries),
new Converter<string, int>(int.Parse));
n = a[0];
v = new Viec[n];
Console.WriteLine(" n = " + n);
int k = 1;
for (int i = 0; i < n; ++i)
v[i] = new Viec(a[k++],a[k++],i+1);
}
public struct Viec
{
public int t; // Thoi han giao nop
public int thuong; // Tien thuong
public int id; // Ma so
public Viec(int th, int thg, int nn)
{ t = th; thuong = thg; id = nn; }
}
} // XepViec
} // SangTao1
Bi 5.3. Xp ba l
C N vt (mt hng), vi mi vt ta bit trng lng v gi tr ca n. Hy xc
nh trng lng cn ly mt s vt xp vo mt ba l c sc cha ti a
l M sao cho gi tr cha trong ba l l ln nht. Gi thit l c th ly mt t
l tu mi vt.
D liu vo: Tp vn bn balo.inp:
Dng u tin: hai gi tr nguyn dng N v M.
N dng tip theo, mi dng cha hai gi tr nguyn dng d v cho mi vt,
trong d l trng lng, v l gi tr tnh theo mt n v trng lng ca
vt (n gi). Cc s cch nhau qua du cch.
BALO.INP
BALO.OUT
C N = 5 vt v sc cha ti a ca ba l l
M = 30 (kg).
5 30
8
8 5
- Vt th nht c trng lng 8, n gi 5
3
tr/kg,
5 4
0
- Vt th hai c trng lng 5, n gi 4,
4 2
3
141
3 8
16 6
- Vt th ba c trng lng 4, n gi 2,
- Vt th t c trng lng 3, n gi 8,
- Vt th nm c trng lng 16, n gi 6.
16
172
Hng dn
C nhiu bi ton thuc h xp ba l, thut ton cho bi ny thuc lp tham lam.
D thy tiu chun chn l gi n v cao. Ta duyt cc vt theo gi n v t cao
tr xung. Vt c chn s c ly ti a. Nh vy, nu tng trng lng cc vt
bng hoc ln hn sc mang ca ba l th bao gi ba l cng c xp .
(*
Pascal
*)
(*-------------------------------BALO.PAS
---------------------------------*)
program balo;
uses crt;
const
MN = 200;
fn = 'BaLo.inp';
gn = 'BaLo.out';
var
a,id: array[1..MN] of integer;{a[i] tr lg vat i}
gdv: array[1..MN] of integer; {gdv[i] don gia vat i}
f, g: text;
n,m: integer; {n: so vat; m: trong luong balo}
t,tt: integer;
{t: tong trong luong con duoc xep vao balo}
{tt: tong gia tri da lay}
(*---------------------------------Doc du lieu
-----------------------------------*)
procedure Doc;
var i,k: integer;
begin
assign(f,fn); reset(f); readln(f,n,m);
for i := 1 to n do read(f,a[i],gdv[i]);
close(f);
end;
(*-----------------------------------Khoi tri cho chi dan
--------------------------------------*)
procedure InitID;
var i: integer;
begin
for i := 1 to n do id[i] := i;
end;
(*-------------------------------------Sap giam theo gia don vi
142
----------------------------------------*)
procedure IDQuickSort(d,c: integer);
var i, j, k, x: integer;
begin
i := d; j := c;
x := gdv[id[(i+j) div 2]]; {phantu giua}
while i <= j do
begin
while gdv[id[i]] > x do inc(i);
while gdv[id[j]] < x do dec(j);
if i <= j then
begin
k := id[i];
id[i] := id[j];
id[j] := k;
inc(i); dec(j);
end;
end;
if d < j then IDQuickSort(d,j);
if i < c then IDQuickSort(i,c);
end;
procedure XepBaLo;
var i: integer;
begin
tt := 0; {tong gia tri }
t := m; {trong luong con lai cua balo }
for i :=1 to n do
if t >= a[id[i]] then
begin { lay tron vat id[i] }
t := t-a[id[i]];
tt := tt + (a[id[i]]*gdv[id[i]]);
end
else { lay cho day balo }
begin
tt := tt+(t*gdv[id[i]]); {lay vua du }
a[id[i]] := t; {chinh lai vat cuoi }
t := 0;
end;
end;
procedure Ghi;
var i: integer;
begin
assign(g,gn); rewrite(g);
for i := 1 to n do writeln(g,a[i]);
writeln(g,tt); close(g);
end;
BEGIN
Doc; InitID; IDQuickSort(1,n);
XepBaLo; Ghi;
END.
// C#
using System;
143
using System.IO;
namespace SangTao1
{
/*-----------------------*
Xep BaLo
* ----------------------*/
class BaLo
{
const string fn = "BaLo.inp";
const string gn = "BaLo.out";
static public Item[] Items;
static public int[] t;
static public int n = 0; // so luong vat
static public int m = 0; // suc chua cua Ba lo
static public int vh = 0; // Gia tri cua balo
static void Main()
{
Doc(); QSort(0, n-1);
Xep(); Ghi();
Test();
Console.WriteLine("\n Fini");
Console.ReadLine();
} // Main
static public void Xep()
{
int th = m; // tr lg con lai cua balo
vh = 0;
t = new int[n];
for (int i = 0; i < n; ++i) t[i] = 0;
for (int i = 0; i < n; ++i)
{
int j = Items[i].Id;
t[j] = Min(th,Items[i].Weight);
th -= t[j];
vh += t[j]*Items[i].Price;
if (th == 0) break;
}
}
static public int Min(int a, int b)
{ return (a < b) ? a : b; }
static public void Ghi()
{
StreamWriter g = File.CreateText(gn);
for (int i = 0; i < n; ++i)
g.WriteLine(t[i]);
g.WriteLine(vh); g.Close();
}
// Sap cac BaLo giam theo tien thuong
static public void QSort(int d, int c)
{
int i = d, j = c;
int m = Items[(d + c) / 2].Price;
Item t = new Item(0,0,0);
144
while (i <= j)
{
while (Items[i].Price > m) ++i;
while (m > Items[j].Price) --j;
if (i <= j)
{
t = Items[i];
Items[i] = Items[j];
Items[j] = t;
++i; --j;
}
}
if (d < j) QSort(d, j);
if (i < c) QSort(i, c);
}
// Doc lai file gn de kiem tra ket qua
static public void Test() t vit
/*---------------------------* Doc du lieu vao mang a
* ---------------------------*/
static public void Doc()
{
char[] cc = new char[]
{'\n',' ','\t','\0','\r'};
int[] b = Array.ConvertAll ((
File.ReadAllText(fn)).
Split(cc, StringSplitOptions.
RemoveEmptyEntries),
new Converter<string, int>(int.Parse));
n = b[0]; // so luong vat
m = b[1]; // gioi han trong luong balo
// Tach du lieu
Items = new Item[n];
for (int k = 2, i = 0; i < n; ++i, k+=2)
Items[i] = new Item(b[k], b[k+1], i);
}
public struct Item // mo ta mot mat hang
{
public int Weight; // trong luong
public int Price; // don gia
public int Id; // ma so
public Item(int w, int p, int i)
{ Weight = w; Price = p; Id = i; }
}
} // BaLo
} // SangTao1
145
(i) P cha tt c cc nh ca G;
(ii) P cha mt s t nht cc cnh ca G;
(iii) P l th lin thng;
(iv) Tng chiu di cc cnh ca P l ngn nht.
th P tho ba tnh cht (i), (ii) v (iii) c gi l cy bao trm ca th G.
Nu P tho thm tnh cht (iv) th P c gi l cy bao trm ngn nht ca G. Mt s
ti liu dng thut ng cy khung thay cho cy bao trm v cy khung cc tiu thay cho
cy bao trm ngn nht.
Bi ton trn c nhiu ng dng thc tin. Mt trong s ng dng c m t
thng qua th d sau:
C n my tnh c ni vi nhau thnh mng bng cp quang l mt loi dy
truyn tin t tin. Trong mng ny, hai my tnh bt k u c th lin lc c vi
nhau trc tip hoc thng qua mt vi my trung gian. Ta gi tnh cht ny l tnh lin
thng ca mng my tnh. Hy b bt mt s dy ni n my tnh trn vn lin thng
c vi nhau. Mng ti thiu thu c chnh l mt cy bao trm ngn nht ca mng
ban u.
D liu vo: tp vn bn tn DOTHI.INP.
Dng u tin ghi hai s t nhin n v m cch nhau qua du cch, biu th
s nh (n) v s cnh (m) ca th.
- Mi dng th i = 1, 2,..., m trong s m dng tip theo ghi ba gi tr x y v d
cch nhau qua du cch vi ngha cnh (x, y) ca th c chiu di d.
D liu ra: tp vn bn tn DOTHI.OUT bao gm:
Thut ton
Ta dng thut gii Kruskal vi k thut nh sau. Duyt cc cnh t chiu di nh
n ln. Cnh c chn s l cnh khng to thnh chu trnh khi ghp n vo th
kt qu.
DOTHI.INP
8 17
1 2 8
1 3 4
1 4 6
1 5 1
1 6 2
2 3 2
2 4 7
3 4 9
3 7 4
3 8 3
4 5 5
4 6 5
4 8 1
5 6 6
6 7 8
6 8 7
7 8 1
ngha: th c 8
nh v 17 cnh.
Cnh (1, 2) di 8,
cnh (1, 3) di 4,
cnh (1, 4) di 6, ...,
cnh (7, 8) di 1 n
v.
DOTHI.OU
T
1 5
4 8
7 8
2 3
1 6
3 8
1 3
14
146
(* Pascal
*)
147
begin
while a[i].len < m do i := i+1;
while a[j].len > m do j := j-1;
if i<=j then
begin
t := a[i];
a[i] := a[j];
a[j] := t;
i := i+1; j := j-1;
end;
end;
if d < j then qsort(d,j);
if i < c then qsort(i,c);
end;
{Tim dai dien cua tap chua x }
function Find(x: integer): integer;
begin
while x <> d[x] do x := d[x];
Find := x;
end;
{-------------------------------Hop nhat 2 tap dinh: tap chua dinh x va tap chua
dinh y.
Union = false: Neu canh (x,y) tao
thanh chu trinh.
Union = true: Neu (x,y) khong tao
thanh chu trinh.
----------------------------------}
function Union(x,y: integer): Boolean;
begin
Union := false;
x := Find(x);
y := Find(y);
if x = y then exit;
if x < y then d[y] := x
else d[x] := y;
Union := true;
end;
procedure CBTNN;(* Cay bao trum ngan nhat *)
var
i, t: integer;
k: integer;
begin
assign(g,gn); rewrite(g);
for i := 1 to n do d[i] := i; {Khoi tri }
k := 0;
t := 0; {tong chieu dai cac canh}
for i := 1 to m do
{duyet cac canh theo chieu dai tang dan }
if Union(a[i].x,a[i].y) then
begin
writeln(g,a[i].x,bl,a[i].y);
t := t + a[i].len;
inc(k);
if k=n-1 then break;{chon duoc n-1 canh la du }
end;
writeln(g,t);
close(g);
end;
BEGIN
Doc; qsort(1,m);
CBTNN; readln;
END.
// C#
using System;
using System.IO;
namespace SangTao1
{
/*-----------------------------------*
Cay khung (cay bao trum)
*
ngan nhat
* -----------------------------------*/
class CayKhung
{
const string fn = "DoThi.inp";
const string gn = "DoThi.out";
// do thi co n dinh
// m canh (u,v)
// u la dinh dau, v - dinh cuoi
// Len - chieu dai canh
static int[] d ; // to chuc Find-Union
static int n = 0; // so dinh cua do thi
static int m = 0; // so canh cua do thi
static Canh[] cc; // Tap cac canh
static int [] t; // canh duoc chon
static int k; // so canh duoc chon
static int sum = 0;
static void Main()
{
Doc(); QSort(0, m-1);
Ghi(); Test();
Console.WriteLine("Fini");
Console.ReadLine();
} // Main
static void Xep()
{
d = new int[n+1];
t = new int [n];
k = 0; sum = 0;
// Khoi tri cho Find-Union
for (int i = 1; i <= n; ++i) d[i] = i;
for (int i = 0; i < m; ++i)
if (Union(cc[i].U,cc[i].V))
{ t[k++] = i; sum += cc[i].Len; }
}
static void Ghi()
{
148
149
StreamWriter g = File.CreateText(gn);
for (int i = 0; i < k; ++i)
cc[t[i]].FWrite(g);
g.WriteLine(sum); g.Close();
}
static int Find(int x)
{
while (d[x] != x) x = d[x];
return x;
}
// Hop nhat 2 tap dinh
// tap chua dinh u va tap chua dinh v
static bool Union(int u, int v)
{
u = Find(u); v = Find(v);
if (u == v) return false;
if (u < v) d[v] = u; else d[u] = v;
return true;
}
// Sap cac canh tang dan theo Len
static void QSort(int d, int c)
{
int i = d, j = c;
int m = cc[(d + c) / 2].Len;
Canh t = new Canh(0,0,0);
while (i <= j)
{
while (cc[i].Len < m) ++i;
while (m < cc[j].Len) --j;
if (i <= j)
{
t = cc[i]; cc[i] = cc[j];
cc[j] = t;
++i; --j;
}
}
if (d < j) QSort(d, j);
if (i < c) QSort(i, c);
}
// Doc lai file gn de kiem tra ket qua
static void Test() t vit
static void Doc()
{
int[] b =
Array.ConvertAll((File.ReadAllText(fn)).Split(
new char[] {'\n',' ','\t','\0','\r'},
StringSplitOptions.RemoveEmptyEntries),
new Converter<string, int>(int.Parse));
n = b[0];// so dinh
m = b[1]; // so canh
// Tach du lieu
cc = new Canh[m];
150
data2.inp
3
3
4
7
12
20
data.out
2
3
3
3
4
5
5
7
10
12
20
151
Thut ton
Ta dng phng php cn. Gi hai tp cha d liu cn trn l f v g, tp cha kt
qu trn l h. Hy tng tng, ta dng tay tri ly ln lt, mi ln mt phn t ca
tp f (ghi vo bin t) v dng tay phi ly ln lt mi ln mt phn t ca tp g (ghi
vo bin p). So snh vt nng trn hai tay t v p. Tay no cm phn t nh hn th t
phn t vo tp kt qu h v do tay ri nn ly tip phn t t tp tng ng. Qu
trnh ny kt thc khi no mt trong hai tp f hoc g c duyt xong. Cui cng ta
chuyn nt cc phn t cn li ca tp cha duyt ht (tp f hoc g) vo tp kt qu h.
Ta cn lu my im sau y:
Khi c xong phn t cui cng ca mt tp th tp chuyn sang trng thi kt
thc (EOF), do nu ta t chc vng lp WHILE trong th tc trn hai tp theo iu
kin (NOT EOF(f)) AND (NOT EOF(g)) th phn t cui ca cc tp s cha
kp c so snh, trong khi ta mun tn trng nguyn tc: sau khi so snh t v p th mt
trong hai bin, t hoc p phi c gii phng. C th thc hin nguyn tc ny bng k
thut sn ui nh sau: dng bin lgic ef ghi nhn trng thi ht tp f sm hn mt
nhp. iu c ngha khi ef=FALSE bin t vn ang cha gi tr cha x l (cha so
snh vi p v do cha c ghi vo tp h). Ch rng d ef = FALSE nhng c
th ta vn c EOF(f)=TRUE. Mt bin eg tng t cng c to cho tp g. V bn
cht c th hiu cc bin ef v eg khi chng nhn gi tr TRUE l thc s c c
1 n v d liu t file.
(*
Pascal
*)
(*---------------------Merge Files
----------------------*)
program MergeFiles;
uses crt;
const
BL = #32; MN = 12;
fn = 'data1.inp'; gn = 'data2.inp';
hn = 'data.out';
{--------------------------------Tron tep fn va gn ghi vao hn
----------------------------------}
procedure FMerge;
var
f,g,h: text;
ef, eg: Boolean;
t, p: integer;
d: longint; {so phan tu trong tep out}
begin
assign(f,fn); reset(f);
assign(g,gn); reset(g);
assign(h,hn); rewrite(h);
ef := SeekEof(f);
if NOT eof then read(f,t);
eg := SeekEof(g);
if NOT eg then read(g,p);
d := 0;
while (NOT ef) AND (NOT eg) do
if t < p then
152
begin
inc(d);
write(h,t,BL);
if d mod 10 = 0 then writeln(h);
ef := SeekEof(f);
if NOT ef then read(f,t);
end else
begin
inc(d);
write(h,p,BL);
if d mod 10 = 0 then writeln(h);
eg := SeekEof(g);
if NOT eg then read(g,p);
end;
while (NOT ef) do
begin
inc(d);
write(h,t,BL);
if d mod 10 = 0 then writeln(h);
ef := SeekEof(f);
if NOT ef then read(f,t);
end;
while (NOT eg) do
begin
inc(d);
write(h,p,BL);
if d mod 10 = 0 then writeln(p);
eg := SeekEof(g);
if NOT eg then read(g,p);
end;
close(f); close(g); close(h);
end;
BEGIN
FMerge;
END.
// C#
using System;
using System.IO;
namespace SangTao1
{
/*-----------------------------------*
Tron 2 files sap tang
* -----------------------------------*/
class TronTep
{
static string gn = "Data.out"; // file ket qua
static string fn1 = "data1.inp"; // input 1
static string fn2 = "data2.inp";// input 2
static void Main()
{
Merge();
Test();
153
Console.WriteLine("\n Fini");
Console.ReadLine();
}
// true neu ki tu c co phai la chu so
static public bool IsDigit(char c)
{ return (c >= '0' && c <= '9'); }
// true neu c la dau + hoac static public bool IsPlusMin(char c)
{ return (c == '+' || c == '-'); }
// true neu c la chu so hoac dau +, static public bool Legal(char c)
{ return IsDigit(c) || IsPlusMin(c); }
// true neu c la dau trang, bao gom
// dau cach, xuong dong, tab, het dong, cuoi string
static public bool IsWhite(char c)
{ return (c==' '||c=='\n'||c=='\t'||c=='\r'||c=='\0'); }
// doc 1 so nguyen co dau
static public bool ReadInt(StreamReader f, ref int s)
{
s = 0;
int sign = 1;
char c = ' ';
while (IsWhite(c) && !f.EndOfStream)
c=(char)f.Read();
if (!Legal(c)) return false;
if (IsPlusMin(c))
{
if (c == '-') sign = -1;
if (f.EndOfStream) return false;
c = (char)f.Read();
while (IsWhite(c) && !f.EndOfStream)
c = (char)f.Read();
if (!IsDigit(c)) return false;
}
while (IsDigit(c))
{
s = s * 10 + (int)(c - '0');
if (f.EndOfStream) break;
c = (char)f.Read();
}
s *= sign;
return true;
}
static void Merge()
{
StreamWriter g = File.CreateText(gn);
StreamReader f1 = File.OpenText(fn1);
StreamReader f2 = File.OpenText(fn2);
int x=0,y=0;
bool b1 = ReadInt(f1, ref x);
bool b2 = ReadInt(f2, ref y);
while (b1 && b2)
{
154
if (x <= y)
{
g.WriteLine(x);
b1 = ReadInt(f1, ref x);
}
else
{
g.WriteLine(y);
b2 = ReadInt(f2, ref y);
}
}
while (b1){g.WriteLine(x);b1=ReadInt(f1,ref x);}
while (b2){g.WriteLine(y);b2=ReadInt(f2,ref y);}
f1.Close(); f2.Close(); g.Close();
}
static void Test()
{
Console.WriteLine("Inp1:\n"+File.ReadAllText(fn1));
Console.WriteLine("Inp2:\n"+File.ReadAllText(fn2));
Console.WriteLine("Out:\n"+File.ReadAllText(gn));
}
} // ChonTep
} // SangTao1
Ch thch Thc ra c th c d liu t hai file vo hai mng tng ng ri trn hai
mng ny. Tuy nhin chng ta mun minh ha li gii vi hn ch l mi ln ch c
php c mt n v d liu t mi file.
Hm bool ReadInt(StreamReader f, ref int i) c mi ln mt s nguyn i t file
text f. Nu c c, hm cho ra gi tr true v s i, ngc li, nu khng gp s
nguyn, hm cho ra gi tr false. Hm hot ng nh sau. Trc ht b qua cc k t
trng. Nu gp du tr - hm ghi nhn du , sau hm c tip dy s v tch ly
dn vo bin nguyn i.
155
Thut ton
Trc ht rng nu trn tp sp tng f gm n phn t vi tp sp tng g gm m
phn t thu c tp sp tng h th i vi cc phn t trong hai tp ngun ta ch cn
thc hin thao tc c, cn thao tc ghi ch thc hin i vi tp ch h. K hiu |f| l s
phn t trong tp f, ta c:
| f | = n, | g | = m
Do tng s cc phn t ca hai tp l m + n nn s phn t trong tp ch h s l
|h|=n+m= |f|+|g|
v do s ln ghi (ti thiu) cc phn t vo tp h s l n + m.
Ta c nhn xt sau: Mun xy dng mt quy trnh trn mi ln hai tp cho nhiu
tp ban u vi yu cu tng s thao tc ghi tp l ti thiu th ta phi to ra cc tp
trung gian cng t phn t cng tt.
Ta dng k hiu f g h vi ngha l trn hai tp ngun f v g thu c tp
h. Ta c
Nu f g h th | h | = |f | + | g |
rng trn tp f vi tp g hay trn tp g vi tp f th s thao tc ghi tp nh
nhau v cng bng | f | + | g |. Gi s ta c ba tp vi s phn t tng ng l
s[1..3] = (5, 1, 2).
Gi s ta thc hin quy trnh ( ) nh sau:
Bc 1: Trn tp vi tp ghi tm vo tp . S thao tc ghi s l (5 + 1) = 6
v tp c 6 phn t.
Bc 2: Trn tp vi tp ghi vo tp . S thao tc ghi s l 6 + 2 = 8 v tp
c 8 phn t.
Kt qu thu c tp . Tng s thao tc ghi trong c hai bc trn s l:
6 + 8 = 14.
Tng qut, vi ba tp a, b v c c trn theo quy trnh:
(a b) c
ta d dng tnh c tng s thao tc ghi tp cho quy trnh trn l
(| a | + | b |) + (| a | + | b |) + c = 2(| a | + | b |) + c.
Bng di y tnh ton cho ba phng n pht hin ra phng n ti u.
156
Phng n
( )
2(5 + 1) + 2 = 2.6 + 2 = 14
( )
2(5 + 2) + 1 = 2.7 + 1 = 15
( )
2(1 + 2) + 5 = 2.3 + 5= 11
(phng n ti u)
Danh sch cc tp
cn x l
Hai tp c s
phn t min
Trn
S thao
tc
ghi tp
(:10,:5,:4,:4,:3)
:3 , :4
(:10,:5,:4,:7)
:5 , :4
(:10,:7, : 9)
:7 , :9
16
(:10,: 16)
:10 , :16
26
Kt
qu
(: 26)
58
157
16
26
10
158
159
for i := 1 to h do
if d[i]=0 then {dinh i chua xu li }
if s[i] < vmin then
begin
vmin := s[i]; imin := i;
end;
d[imin] := 1; min1 := imin;
end;
Sau khi to xong cy Huffman, ghi kt qu, ta ch cn duyt cc nh c to
mi, tc l cc nh c m s t n + 1 n h = 2n 1 ly hai con tri v phi ca
mi nh.
{--------------------------------Duyet cac dinh tu n+1
den 2n-1,
ghi thong tin vao tep.
----------------------------------}
procedure Ghi;
var i: integer;
begin
assign(g,gn);
rewrite(g);
writeln(g,n-1);
for i := n+1 to h do
writeln(g,t[i],BL,p[i],BL,i);
writeln(g,tt);
close(g);
end;
(* Pascal *)
(*----------------------------------Tron nhieu tep
------------------------------------*)
uses crt;
const
fn = 'MF.INP';
gn = 'MF.OUT';
MN = 200;
BL = #32; {Dau cach}
NL = #13#10; {xuong dong}
type
MI1 = array[0..MN] of integer;
MB1 = array[0..MN] of byte;
var
s,t,p: MI1;
{s[i] - so phan tu trong tep i}
{t[i] - tro trai}
{p[i] - tro phai i}
// C#
using System;
using System.IO;
namespace SangTao1
{
/*---------------------------*
Cay Huffman
*
Tron n file sap tang
* --------------------------*/
160
class HuffmanTree
{
static string fn = "MF.inp"; // file ket qua
static string gn = "MF.out"; // file ket qua
static int[] t; // tro trai
static int[] p; // tro phai
static int[] v; // trong so dinh
static int[] d; // danh dau dinh da xu ly
static int n = 0; // so phan tu
static int n2; // n2 = 2*n
static int h = 0; // Goc cua cay Huffman
static int tt = 0; // tong trong so
static void Main()
{
Doc(); Huffman();Ghi(); Test();
Console.WriteLine("\n Fini");
Console.ReadLine();
} // Main
static void Ghi()
{
StreamWriter f = File.CreateText(gn);
for (int i = n + 1; i <= h; ++i)
f.WriteLine(t[i] + " " + p[i] + " " + i);
f.WriteLine(tt);
f.Close();
}
static void Huffman()
{
h = n; // goc cay Huffman
tt = 0; // tong trong so
int m1 = 0, m2 = 0;
int x;
for (int i = 1; i < n; ++i)
{
m1 = MinV(); m2 = MinV();
if (m1 > m2)
{x = m1; m1 = m2; m2 = x;}
// m1 < m2
++h; // them dinh moi
v[h] = v[m1] + v[m2];
t[h] = m1; // tro trai
p[h] = m2; // tro phai
tt += v[h];
}
}
// Tim dinh chua xu ly co trong so min
static int MinV()
{
int imin = 0;
for (int i = 1; i <= h; ++i)
if (d[i] == 0) // dinh i chua x li
if (v[i] < v[imin]) imin = i;
161
162
Ch
Thut ng tham lam khng c ngha l ly nhiu nht m ch l xc nh mt
chin lc x l d liu sao cho c hiu qu nht.
163
CHNG 6
end;
if (Tm c 1 nc i)
then Tin
else
if (c th li c)
then Li
else
begin
Ghi nhn: v nghim;
exit;
end;
until false;
164
end;
if (Ht kh nng duyt)
then
begin
Ghi nhn v nghim;
exit;
end;
if (Tm c 1 nc i)
then Tin
else Li;
until false;
Thng thng ta khi tr cho v l dy rng (khng cha phn t no) hoc dy
c mt phn t. Ta ch yu cu dy v c khi tr sao cho v tho P. Lu l c
dy v tho P ch khng phi tng phn t trong v tho P.
C bi ton yu cu tm ton b (mi nghim) cc dy v tho ng thi hai tnh
cht P v Q. Nu bit cch tm mt nghim ta d dng suy ra cch tm mi nghim
nh sau: mi khi tm c mt nghim, ta thng bo nghim trn mn hnh hoc
ghi vo mt tp ri thc hin thao tc Li, tc l gi v nh khng cng nhn
nghim , do phi loi v[i] cui cng trong dy v tip tc tm hng khc.
Phng php ny c tn l phng php gi sai. Hai s trn s c sa mt
cht nh sau tm mi nghim.
S 3: Gii bi ton quay lui
(tm mi nghim)
Khi tr: v tho P;
d := 0; {m s nghim}
repeat
if (v tho Q) then
begin
d
:=
d+1;
Ghi nhn nghim th d;
Li; { gi sai }
end;
if (Tm c 1 nc i)
then Tin
else if (c th li c)
then Li
else { ht kh nng }
begin
if d = 0 then
Ghi nhn: v nghim;
else
Ghi nhn: d nghim;
exit;
end;
until false;
Bi 6.1. Cc qun Hu
Qun Hu trn bn c Vua c th n theo hng, theo ct cha n hoc theo
ng cho ca hnh vung nhn n lm nh.
165
Thut ton
Trc ht ta t cc qun Hu mp ngoi bn c. Hu th i s ng u ct th
i. Sau ta dch dn cc Hu vo trong cc dng ca bn c v ghi nhn v tr ca
chng vo mt mng v. Phn t v[i] ca mng v cho bit phi t Hu th i, tc l Hu
chim ct i ti dng v[i].
Th d, vi bn c 4 4 ta c li gii v = (2, 4,
1, 3) vi ngha:
- t Hu th nht ti (ct 1) dng 2,
Hu th 2 ti (ct 2) dng 4, Hu th
3 ti (ct 3) dng 1 v Hu th 4 ti
(ct 4) dng 3.
- Mi khi t c Hu th i ta chuyn
qua Hu tip theo i + 1. iu kin t
c Hu i trn dng d ca bn c l
n khng b cc Hu t trc ,
tc l cc Hu j = 1..(i - 1) chiu. y
chnh l tnh cht P.
- Hu j < i chiu (ng ) Hu i khi v ch khi v[j] = v[i] (cng hng) hoc i - j
= abs(v[i] - v[j]) (Hu i v Hu j nm trn hai nh i din ca hnh vung, do
hai cnh lin tip ca hnh vung ny phi bng nhau).
- Tnh cht Q khi s l: t c N Hu.
S tm mt nghim XepHau1 nh sau:
(*-----------------------------------Tim 1 nghiem: xep M quan hau tren
ban co M X M
------------------------------------*)
procedure XepHau1(M: byte);
var i: byte;
begin
if (M < 1) or (M > MN) then exit;
{MN = 20 la gioi han kich thuoc ban co}
n :=
M;
{Khi tr: t cc hu 1..N ngoi bn c.
Hu i t ti u ct i, i=1..N.}
for i := 1 to n do v[i] := 0;
i := 1; {Hu ang xt}
repeat
if i > n then {co nghiem v[1..n]}
begin
KetQua1(n);
exit;
end;
if i < 1 then {vo nghiem}
begin
KetQua1(0);
exit;
166
end;
if Tim(i) {co cach di }
then inc(i) {Tien}
else
begin {Lui}
v[i] := 0;
dec(i);
end;
until false;
end;
Th tc c hai tnh hung, KetQua1(n): hin th mng v[1..n], trong v[i] l
dng t Hu i, KetQua1(0): thng bo v nghim.
Hm Tim(i) thc hin chc nng sau y: xut pht t dng Hu i ang ng l
v[i] y tip Hu i xung cc dng di tm c mt dng t n sao cho khng b
cc Hu t trc , tc l khng b cc Hu j = 1..(i 1) n.
Tim(i)=true: tm c mt v tr (dng) t Hu i, ngc li Tim=false.
(*--------------------------------------Xuat phat tu dong v[i]+1, tim dong moi
co the dat duoc Hau i
--------------------------------------*)
function Tim(i: byte): Boolean;
begin
Tim := true;
while v[i] < n do
begin
inc(v[i]);
if DatDuoc(i) then exit;
end;
Tim := false;
end;
Hm Boolean DatDuoc(i) cho gi tr true nu Hu i khng b cc Hu
j = 1, 2,, i 1 t trc n. Ngc li, nu Hu i b mt Hu no n th hm
cho ra gi tr false.
(*-------------------------------------Kiem tra xem co dat duoc Hau i
tai o (v[i],i) cua ban co khong ?
--------------------------------------*)
function DatDuoc(i: byte): Boolean;
var j: byte;
begin
DatDuoc := false;
for j := 1 to i-1 do
if (v[i] = v[j]) or (i-j = abs(v[i]-v[j]))
{Hau j an duoc Hau i}
then exit;
DatDuoc := true;
end;
Thao tc Tin n gin l chuyn qua xt Hu k tip, Hu i + 1.
Tien: Chuyn qua Hu tip theo
inc(i);
167
(*
Pascal
*)
(*============================
N Hau
==============================*)
{$B-}
uses crt;
const
MN = 20;
168
gn = 'N_HAU.OUT';
BL = #32; {dau cach}
var
v: array[0..MN] of byte;
n: byte; {so quan hau, kich thuoc ban co}
g: text; {tep ket qua}
function DatDuoc(i: byte): Boolean; t vit
function Tim(i: byte): Boolean; t vit
(*--------------------------------------Hien thi nghiem tren man hinh
Cho bai toan tim 1 nghiem
k=0: vo nghiem
k=n: co nghiem v[1..n]
--------------------------------------*)
procedure KetQua1(k: byte);
var i: byte;
begin
writeln;
if k = 0 then write('Vo nghiem')
else
for i := 1 to k do write(v[i]:3);
writeln;
end;
(*-----------------------------------Tim 1 nghiem: xep M quan hau tren
ban co M X M
------------------------------------*)
procedure XepHau1(M: byte); t vit
(*--------------------------------------Ghi nghiem thu d vao tep g 'N_Hau.out'
Bai toan tim moi nghiem
--------------------------------------*)
procedure KetQua(d: integer);
var i: byte;
begin
write(g,'Nghiem thu ',d,': ');
for i := 1 to n do write(g,v[i],BL);
writeln(g);
end;
(*--------------------------------------Tim moi cach dat M Hau tren ban co M X M
--------------------------------------*)
procedure XepHau(M: byte); t vit
BEGIN
XepHau1(8); {tim 1 nghiem}
XepHau(8); {tim du 92 nghiem}
END.
Phng n ci tin
Ta xt mt phng n ci tin tp trung vo vic nng cao tc tnh ton khi
kim tra hai hu ng nhau. Mi khi tm v tr t hu th i trn bn c ta cn kim
169
(*
Pascal
*)
(*============================
N Hau
==============================*)
{$B-}
uses crt;
const
MN = 20;
gn = 'N_HAU.OUT';
BL = #32; {dau cach} nl = #13#10; { Chuyen dong }
type
mi1 = array[0..MN] of integer;
var
v: mi1; { vi tri dat hau }
c1: array[-mn..mn] of integer; { cheo 1 }
c2: array[0..2*mn] of integer; { cheo 2 }
dd: mi1;
{ dong }
n: integer; { so quan hau, kich thuoc ban co }
g: text; { file ket qua }
(*-------------------------Nhac Hau i khoi ban co
--------------------------*)
procedure NhacHau(i: integer);
begin
if v[i] = 0 then exit;
c1[i-v[i]] := 0; c2[i+v[i]]
:=
0;
dd[v[i]] := 0;
end;
(*-------------------------Dat Hau i vao dong j
--------------------------*)
procedure DatHau(i,j: integer);
begin
c1[i-j] := 1; c2[i+j] := 1;
dd[j] := 1;
end;
(*--------------------------------------Xuat phat tu dong v[i]+1,
tim dong j co the dat duoc Hau i
--------------------------------------*)
function Tim(i: integer): integer;
var j: integer;
begin
Tim := 0;
for j := v[i] + 1 to n do
if ( c1[i-j] + c2[i+j] + dd[j] = 0 ) then
begin
Tim := j;
exit;
end;
end;
(*--------------------------------------Hien thi nghiem tren man hinh
Cho bai toan tim 1 nghiem
k = 0: vo nghiem
k = n: co nghiem v[1..n]
--------------------------------------*)
procedure Ket1(k: integer);
var i: integer;
begin
writeln;
if k = 0 then write('Vo nghiem')
else for i := 1 to k do write(v[i]:3);
writeln;
end;
(*-------------------------------------Tim 1 nghiem: xep M quan hau tren
ban co M X M
--------------------------------------*)
procedure XepHau1(M: integer);
var i,j: integer;
begin
if (M < 1) or (M > MN) then exit;
fillchar(c1,sizeof(c1),0);
fillchar(c2,sizeof(c2),0);
fillchar(dd,sizeof(dd),0);
fillchar(v,sizeof(v),0);
n := M; i := 1; { Dang xet Hau i }
170
repeat
if i > n then
begin
Ket1(n); { co nghiem v[1..n] }
exit;
end;
if i < 1 then
begin
Ket1(0); {vo nghiem}
exit;
end;
NhacHau(i); j := Tim(i);
if j > 0 then
begin { Tien: Dat Hau i tai dong j }
DatHau(i,j);
v[i] := j; inc(i); { Xet Hau i+1 }
end
else
begin { Lui: Dat Hau i ra ngoai ban co }
v[i] := 0; dec(i); { Xet Hau i-1 }
end;
until false;
end;
(*--------------------------------------Ghi nghiem thu d vao tep g 'N_Hau.out'
Bai toan tim moi nghiem
--------------------------------------*)
procedure Ket(d: integer);
var i: integer;
begin
write(g,'Nghiem thu ',d,': ');
for i := 1 to n do write(g,v[i],BL);
writeln(g);
end;
(*--------------------------------------Tim moi cach dat M Hau
tren ban co M X M
--------------------------------------*)
procedure XepHau(M: integer);
var i,j: integer;
d: integer; { dem so nghiem }
begin
if (M < 1) or (M > MN) then exit;
n := m;
fillchar(v,sizeof(v),0);
fillchar(c1,sizeof(c1),0);
fillchar(c2,sizeof(c2),0);
fillchar(dd,sizeof(dd),0);
assign(g,gn); rewrite(g);
i := 1; {Hau dang xet}
d := 0; {dem so nghiem}
repeat
if i > n then
171
begin
inc(d);
Ket(d); { v[1..n] la nghiem thu d }
i := n;
end;
if i < 1 then
begin
writeln(g,'Tong cong ',d,' nghiem ');
close(g);
writeln('Xem ket qua trong file ',gn);
exit;
end;
NhacHau(i); j := Tim(i);
if j > 0 then
begin { Tien }
DatHau(i,j); v[i] := j; inc(i);
end
else
begin { Lui }
v[i] := 0; dec(i);
end;
until false;
end;
procedure Test;
begin
XepHau1(8); { tim 1 nghiem }
XepHau(8); { tim du 92 nghiem }
readln;
end;
BEGIN
Test;
END.
// C#
using System;
using System.IO;
namespace SangTao1
{
/*-----------------------------------*
Bai toan Tam Hau
*
Phuong an tong quat cho N Hau
* -----------------------------------*/
class TamHau
{
static int mn = 20;
static int mn2 = 2 * mn;
static int[] v = new int[mn + 1];
// Vet tim kiem, v[i] - dong dat Hau i
static int[] dd = new int[mn + 1];
// dd[i] = 1: dong i bi cam
static int[] c1 = new int[mn2 + 1];
// c1[i] = 1 duong cheo chinh i bi cam
static int[] c2 = new int[mn2 + 1];
172
173
174
175
}
// Dich hau k tu vi tri hien tai v[k]
// xuong den dong cuoi (n)
// tim mot vi tri dat hau k
static int TimNuocDi(int k)
{
for (int i = v[k] + 1; i <= n; ++i)
if ((dd[i] + c1[n+(k-i)] + c2[k+i]) == 0)
return i;
return 0;
}
static void Print(int[] a, int n)
{
for (int i = 1; i <= n; ++i)
Console.Write(a[i] + " ");
}
} // TamHau
} // SangTao1
Bi 6.2. T chun
Mt t loi M l mt dy cc ch s, mi ch s nm trong khong t 1 n M.
S lng cc ch s c mt trong mt t c gi l chiu di ca t . T
loi M c gi l t chun nu n khng cha hai khc (t con) lin nhau m
ging nhau.
a) Vi gi tr N cho trc, hin th trn mn hnh mt t chun loi 3 c chiu
di N.
b) Vi mi gi tr N cho trc, tm v ghi vo tp vn bn tn TUCHUAN.OUT
mi t chun loi 3 c chiu di N.
1 N 40000.
Th d:
1213123 l t chun loi 3, chiu di 7.
1213213 khng phi l t chun v n cha lin tip hai t con ging nhau l
213.
Tng t, 12332 khng phi l t chun v cha lin tip hai t con ging
nhau l 3.
Bi gii
Ta dng mng v[1..n] lu t cn tm. Ti mi bc i ta xc nh gi tr v[i] trong
khong 1..m sao cho v[1..i] l t chun.
iu kin P: v[1..i] l t chun.
iu kin Q: Dng thut ton theo mt trong hai tnh hung sau y:
nu i = n th bi ton c nghim v[1..n].
nu i = 0 th bi ton v nghim.
TimTu1: Tm mt nghim.
{Khi tr mi v tr bng 0 }
for i := 1 to n do v[i] := 0;
i := 1;
repeat
if i > n then {co nghiem v[1..n]}
begin
KetQua1(n); {in nghiem v[1..n]}
176
exit;
end;
if i < 1 then {vo nghiem}
begin
KetQua1(0);
exit;
end;
j := Tim(i);
if j > 0 then
begin
v[i] :=
j;
inc(i) {tin}
end
else
begin {Li}
v[i] := 0;
dec(i);
end;
until false;
Hm Tim hot ng nh sau: duyt cc gi tr ti v tr v[i] ca t v[1..i] k t
v[i] + 1 n m sao cho v[1..i] l t chun.
Tim = true nu tn ti mt gi tr v[i] nh vy. Ngc li, nu vi mi
v[i] = v[i] + 1..m t v[1..i] u khng chun th Tim = false.
function Tim(i: integer): Boolean;
begin
Tim := true;
while v[i] < 3 do
begin
inc(v[i]);
if Chuan(i) {v[1..i] la tu chuan}
then exit;
end;
Tim := false;
end;
kim tra tnh chun ca t v[1..i], ta lu rng t v[1..i-1] chun (tnh cht
P), do ch cn kho st cc cp t c cha v[i], c th l kho st cc cp t c chiu
di k ng cui t v. l cc cp t v[(ikk+1)..(ik)] v v[ik+1..i] vi k = 1..(i div
2). Nu vi mi k nh vy hai t u khc nhau th Chuan=true. Ngc li, Chuan
= false.
function Chuan(i: integer): Boolean;
var k: integer;
begin
Chuan := false;
for k := 1 to (i div 2) do
if Bang(i,k) then exit;
Chuan := true;
end;
Hm Bang(i,k) kim tra xem hai t k nhau chiu di k tnh t i tr v trc c
bng nhau hay khng.
Hai t c xem l khc nhau nu chng khc nhau ti mt v tr no .
function Bang(i,k: integer): Boolean;
var j: integer;
begin
Bang := false;
for j := 0 to k-1 do
if v[i-j] <> v[i-k-j] then exit;
Bang := true;
end;
Th tc TimTu tm mi nghim ca bi ton.
(*
Pascal *)
(*-----------------------Tu chuan
-----------------------*)
{$B- }
uses crt;
const
MN = 40; {Cho cau b: tim moi nghiem }
MN1 = 40000; {Cho cau a: tim 1 nghiem }
gn = 'TuChuan.OUT';
var
v: array[0..MN1] of byte; {chua nghiem }
n: integer; {chieu dai tu: tinh chat Q }
g: text; {output file }
(*---------------------------------------Kiem tra hai tu ke nhau, chieu dai k
tinh tu vi tri i tro ve truoc co bang nhau ?
----------------------------------------*)
function Bang(i,k: integer): Boolean; t vit
(*------------------------------------------Kiem tra tu v[1..i] co la tu chuan ?
------------------------------------------*)
function Chuan(i: integer): Boolean; t vit
(*-----------------------------------Sua v[i] de thu duoc tu chuan
Tim = true: Thanh cong
Tim = false: That bai
-------------------------------------*)
function Tim(i: integer): Boolean; t vit
(*------------------------------------Hien thi ket qua, tu v[1..n]
(Cau a: tim 1 nghiem)
-------------------------------------*)
procedure KetQua1(k: integer);
var i: integer;
begin
writeln;
if k = 0 then write('Vo nghiem')
else for i := 1 to k do write(v[i]);
writeln;
end;
(*---------------------------------------Quay lui: tim 1 nghiem cho bai toan
tu chuan chieu dai len, chi chua cac
177
chu so 1..lim
----------------------------------------*)
procedure TimTu1(len: integer); t vit
(*-------------------------------Test cau a: Tu chuan dai 200
chi chua cac chu so 1, 2, 3
--------------------------------*)
procedure Test1;
begin
clrscr;
TimTu1(200);
readln;
end;
(*--------------------------------Ghi mot nghiem vao file
---------------------------------*)
procedure KetQua(d: integer);
var i: integer;
begin
if d = 0 then write(g,'Vo nghiem')
else
begin
write(g,'Nghiem thu ',d,': ');
for i := 1 to n do write(g,v[i]);
writeln(g);
end;
end;
(*-------------------------------------------Cau b: Liet ke toan bo cac tu chuan
chieu dai len, chi chua cac chu so 1, 2,3
---------------------------------------------*)
procedure TimTu(len: integer);
var
i: integer;
d: longint;
begin
if (len < 1) or (len > MN) then exit;
n := len;
for i := 1 to n do v[i] := 0;
assign(g,gn);
rewrite(g);
i := 1;
d := 0;
repeat
if i > n then {tim duoc 1 nghiem v[1..n]}
begin
inc(d);
KetQua(d);
i := n;
end;
if i < 1 then {da vet het}
begin
if d = 0 then KetQua(0);
178
179
close(g);
write('OK'); readln;
exit;
end;
if Tim(i) then inc(i) {tin }
else
{Lui }
begin
v[i] := 0;
dec(i);
end;
until false;
end;
(*-----------------------------------------Test cau b: Liet ke toan bo cac
tu dai 16, chi chua cac chu so 1, 2,3
Ket qua ghi trong tep TuChuan.out
------------------------------------------*)
procedure Test;
begin
clrscr;
TimTu(16);
end;
BEGIN
Test;
END.
Vi N = 16, M = 3, c tng cng 798 nghim, tc l 798 t chun chiu di 16 to
t cc ch s 1, 2 v 3. Di y l 20 nghim u tin tm c theo thut ton.
Nghiem thu 1: 1213123132123121
Nghiem thu 2: 1213123132123213
Nghiem thu 3: 1213123132131213
Nghiem thu 4: 1213123132131231
Nghiem thu 5: 1213123132131232
Nghiem thu 6: 1213123132312131
Nghiem thu 7: 1213123132312132
Nghiem thu 8: 1213123132312321
Nghiem thu 9: 1213123212312131
Nghiem thu 10: 1213123212312132
Nghiem thu 11: 1213123212313212
Nghiem thu 12: 1213123212313213
Nghiem thu 13: 1213123212313231
Nghiem thu 14: 1213123213121321
Nghiem thu 15: 1213123213121323
Nghiem thu 16: 1213123213231213
Nghiem thu 17: 1213123213231232
Nghiem thu 18: 1213123213231321
Nghiem thu 19: 1213212312131231
Nghiem thu 20: 1213212312131232
180
// C#
using System;
using System.IO;
namespace SangTao1
{
/*-----------------------*
Tu chuan
* -----------------------*/
class TuChuan
{
static int mn = 500000;
static string fn = "TuChuan.out";
static int[] v = new int[mn + 1];
static int n = 0; // kich thuoc ban co
static int k = 0;
static void Main()
{
int sl = 10;
Console.WriteLine("Test 1: Tim 1 nghiem voi n = "+sl);
Test1(sl);
Console.WriteLine("Test 2: Tim moi nghiem voi n "+sl);
Test2(sl);
Console.WriteLine("\n Doc lai Ket qua:\n");
Console.WriteLine(File.ReadAllText(fn));
Console.WriteLine("\n Fini");
Console.ReadLine();
}
// Test 2: tim moi nghiem
static void Test2(int sl)
{
Console.WriteLine(" Tong cong " +
TimMoiTu(sl) + "
nghiem");
}
// Tim moi nghiem. Phuong phap gia sai
static int TimMoiTu(int len)
{
if (len > mn || len < 1) return 0;
StreamWriter f = File.CreateText(fn);
n = len;
int soNghiem = 0;
Array.Clear(v,0,v.Length);
k = 1;
do
{
if (k > n)
{
++soNghiem;
for (int i = 1; i <= n; ++i)
f.Write(v[i]);
f.WriteLine();
k = n;
}
181
if (k < 1)
{
f.WriteLine(soNghiem);
f.Close();
return soNghiem;
}
if (CoNuocDi()) k++;// tien
else v[k--] = 0; // lui
} while (true);
}
// Test 1: tim 1 nghiem
static void Test1(int sl)
{
if (TimTu(sl)) Print(v, n);
else Console.WriteLine("\n Vo Nghiem");
}
static bool TimTu(int len)
{
if (len > mn || len < 1) return false;
n = len;
for (int i = 0; i <= n; ++i) v[i] = 0;
k = 1;
do
{
if (k > n) return true;
if (k < 1) return false;
if (CoNuocDi()) k++;// tien
else v[k--] = 0; // lui
} while (true);
}
static bool CoNuocDi()
{
while (v[k] < 3)
{
++v[k];
if (Chuan()) return true;
}
return false;
}
// Kiem tra v[1..k] la tu chuan
static bool Chuan()
{
int k2 = k / 2;
for (int j = 1; j <= k2; ++j)
if (Bang(j)) return false;
return true;
}
// v[k-2d+1..k-d]==v[k-d+1..k] ?
static bool Bang(int d)
{
int kd = k - d;
for (int i = 0; i < d; ++i)
if (v[k - i] != v[kd - i]) return false;
182
return true;
}
static void Print(int[] a, int n)
{ // moi dong 50 ki tu
for (int i = 1; i <= n; ++i)
Console.Write(a[i]+
((i%50==0)?"\n":""));
Console.WriteLine();
}
} // TuChuan
} // SangTao1
Th d:
cho bit:
Dng 0: 9 6 7 - m cung gm 9 nh m
s 1..9, cn tm ng i t nh 6 n nh 7.
- Dng 1: 1 0 1 1 1 0 0 0 - nh 1 c ni
vi cc nh 2, 4, 5, v 6. Khng c cnh ni nh 1
vi cc nh 3, 7, 8 v 9.
- ...
- Dng 8: 1 nh 8 c ni vi nh 9.
V th l v hng nn cnh ni nh x vi
nh y cng chnh l cnh ni nh y vi nh x.
Thng tin v nh N khng cn thng bo, v vi
mi nh i ta ch lit k cc nh j > i to thnh cnh (i, j).
Kt qu ra ghi trong tp vn bn MECUNG.OUT:
9
1
1
0
0
0
0
0
1
MECUNG.INP
6 7
0 1 1 1 0 0 0
1 0 0 0 0 0
0 0 1 0 0
1 1 0 0
0 0 0
0 0
0
MECUNG.OUT
5
6 4 2 3 7
T nh 6 c th n c nh 7, qua 5 nh theo
ng bn khc:
6 4 2 3 7.
183
8
7
41
Thut ton
Xut pht t nh v[1] = s, mi bc lp i ta thc hin cc kim tra sau. Gi k l s nh
i qua v c tch lu trong mng gii trnh ng i v, c th l xut pht t nh v[1]
= s, sau mt s ln duyt ta quyt nh chn ng i qua cc nh v[1], v[2], v[3],, v[k].
C th gp cc tnh hung sau:
a) (n ch?) nu v[k] = t tc l n c nh t: thng bo kt qu, dng thut
ton, ngc li thc hin b.
b) (Tht bi?) k = 0: nu quay tr li v tr xut pht v[i] = s m t khng cn
ng i no khc th phi li mt bc na, do k = 0. Trng hp ny chng t bi
ton v nghim, tc l, do th khng lin thng nn khng c ng i t nh s n
nh t. Ta thng bo v nghim v dng thut ton.
c) (i tip?) nu t nh v[k] tm c mt cnh cha i qua v dn n mt nh i
no th tin theo ng , nu khng: thc hin bc d.
d) (Li mt bc) B nh v[k], li li nh v[k-1].
Thut ton trn c tn l si ch Arian c phng theo mt truyn thuyt c
Hy Lp sau y. Anh hng Te-dy phi tm dit con qui vt nhn ngu (u ngi,
mnh tru) Minotav n nu trong mt phng ca m cung c nhiu ng ngch rc ri
tng lm lc bc nhiu dng s v nhng ngi ny u tr thnh nn nhn ca
Minotav. Ngi yu ca chng Te-dy l cng cha ca x Mino a cho chng mt
cun ch v dn chng nh sau: Chng hy buc mt u ch vo ca m cung (phng
xut pht s), sau , ti mi phng trong m cung, chng hy tm xem c Minotav n
trong khng. Nu c, chng hy chin u dng cm h th n ri cun ch quay
ra ca hang, ni em trng ngng chng. Nu cha thy Minotav ti phng , chng
hy kim tra xem ch c b ri hay khng. Cun ch bt u ri khi no t phng chng
ng c hai si ch i ra hai ca khc nhau. Nu ch ri nh vy, chng hy cun ch li
li mt phng v nh nh du ng i khi lc bc vo ln th hai.
Nu khng gp ch ri th chng hy yn tm d tm mt ca cha i qua phng
khc. i n u chng nh nh ch theo n . Nu khng c ca i tip hoc t phng
chng ang ng, mi ca ra u c chng i qua ri, th chng hy cun ch li li
mt phng ri tip tc tm ca khc.
Ta xut pht t s tng qut cho lp bi ton quay lui.
(*
Pascal
184
*)
185
assign(f,fn);
reset(f);
read(f,n,s,t);
fillchar(a,sizeof(a),0);
if (n < 1) or (n > MN) then exit;
for i := 1 to n-1 do
for j := i+1 to n do
begin
read(f,a[i,j]);
a[j,i] := a[i,j]; {lay doi xung }
end;
close(f);
end;
Th tc Xem hin th d liu trn mn hnh kim tra vic c c ng khng.
Vi nhng ngi mi lp trnh cn lun lun vit th tc Xem. Khi np bi th c th b
li gi th tc ny. Cc hng kiu string bl = #32 l m ASCII ca du cch,
hng nl = #13#10 l mt xu cha hai k t iu khin c m ASCII l xung dng
#13, tc l ng vi phm RETURN v a con tr mn hnh v u dng #10. Khi
lnh writeln s tng ng vi lnh write(nl).
(*-----------------------Xem du lieu
-------------------------*)
procedure xem;
var i,j: byte;
begin
write(nl,n,bl,s,bl,t,nl);
for i := 1 to n do
begin
for j := 1 to n do
write(a[i,j],bl);
write(nl);
end;
end;
Th tc Ket(k) - ghi ng i v[1..k] t s n t tm c vo tp output.
Ket(0): thng bo v nghim.
(*-----------------------------Ghi ket qua.
k = 0: vo nghiem
k > 0: co duong tu s den t
gom k canh
------------------------------*)
procedure Ket(k: byte);
var i: byte;
begin
assign(g,gn); rewrite(g);
write(g,k,nl);
if k > 0 then
begin
write(g,v[1]);
for i := 2 to k do
write(g,bl,v[i]);
186
end;
close(g);
end;
Hm Tim - t nh v[k] tm mt bc i n nh i. iu kin: i phi l nh cha
thm v ng nhin c cnh i t v[k] n i, ngha l gi tr a[v[k], i] trong ma trn k
phi l 1. Ta dng mt mng d nh du nh i thm cha. d[i] = 0 nh i cha
thm, d[i] = 1 nh i thm v tng c chn a vo mng v l mng gii
trnh ng i. Nu tm kim thnh cng ta gn cho hm Tim gi tr i, chnh l nh cn
n. Ngc li, khi vic tm kim tht bi, ngha l khng tm c nh i c th i
t nh v[k] n , ta gn cho hm Tim gi tr 0.
Ta lu l mi nh ch i n khng qu mt ln. ng nhin khi li th ta buc
phi quay li nh n, do , chnh xc hn ta phi gi d[i]=1 l gi tr nh du khi
tin n nh i.
(*------------------------------------Tu dinh v[k] tim duoc mot buoc di
den dinh i. Dieu kien:
d[i] = 0 - dinh i chua xuat hien
trong lich trinh v
d[i] = 1 - dinh i da xuat hien
trong lich trinh v.
--------------------------------------*)
function Tim: byte;
var i: byte;
begin
Tim := 0;
for i := 1 to n do
if d[i] = 0 then {dinh i chua tham }
if a[v[k],i] = 1 {co duong tu v[k] den i }
then
begin
Tim := i;
exit;
end;
end;
Nu tm c nh cha thm tho cc iu kin ni trn ta tin thm mt bc
theo cnh (v[k], i). Ta cng nh du nh i l thm bng lnh gn d[i]: = 1. l
ni dung ca th tc NhaChi (nh ch).
(*--------------------------Di 1 buoc tu v[k] den i
----------------------------*)
procedure NhaChi(i: byte);
begin
inc(k);
v[k] := i; {tien them 1 buoc }
d[i] := 1; {danh dau dinh da qua }
end;
Nu t nh v[k] ta khng tm c nh no i tip th ta phi thc hin th tc
CuonChi (cun ch) nh di y. Th tc ny ch n gin l li mt bc t nh
Te-dy hin ang ng tr v nh trc , nu c, tc l k 1, ta nh du cnh (v[k 1], v[k]) l i hai ln. Ta nhn xt rng, nu khng tnh ln tr li mt nh khi phi
187
(*
Pascal
*)
188
189
{
f.WriteLine(k);
for (int i = 1; i <= k; ++i)
f.Write(v[i] + " ");
}
else f.WriteLine(0);// vo nghiem
f.Close();
}
static bool MC()
{
Array.Clear(v, 0, v.Length);
Array.Clear(v, 0, v.Length);
k = 1; // Buoc duyet
v[k] = s; d[s] = 1;
// danh dau phong da den
int phong = 0;
do
{
if (v[k] == t)
return true; // den dich
if (k < 1)
return false; // het cach
if ((phong = Tim()) > 0)
{ // Tien them 1 buoc
// nha chi, danh dau
v[++k] = phong; d[phong] = 1;
}
else --k; // lui
} while (true);
}
// Tu phong v[k] tim duoc
//mot duong sang phong khac
static int Tim()
{
for (int j = 1; j <= n; ++j)
if (d[j] == 0)// phong j chua tham
if (c[v[k], j] > 0)
//co hanh lang toi j
return j;
return 0;
}
} // MeCung
} // SangTao1
190
191
CHNG 7
QUY HOCH NG
2.
3.
192
Phng n
10
11
Bi gii
1. Lp h thc
Gi Chia(i, j) l s cch chia i phn thng cho j hc sinh, ta thy:
Chia(i, j)
j=0
Chia(i, j) = 0
i = 0 and j 0
Chia(i, j) = 1
193
i<j
Chia(i, j) = Chia(i, i)
ij
j-1
i-j
...
j
[i-j,j]
...
194
const
[i,j-1]
[i,j]
i
MN = 70;{ gioi han tren
cua m va n }
type
ml1 = array[0..MN] of longint;
ml2 = array[0..mn] of ml1;
var cc: ml2;
Ta quy c cc[i, j] cha s cch chia i phn thng cho j hc sinh.
Theo phn tch ca phng n 1, ta c:
cc[0, 0] = 1; cc[i, 0] = 0, vi i:=1..m.
cc[i, j] = cc[i, i], nu i < j
cc[i, j] = cc[i, j-1]+cc[i-j, j], nu i j.
T ta suy ra quy trnh in tr vo bng cc nh sau:
Khi tr
cc[0,0 ]:= 1;
vi i := 1..m: cc[i,0] := 0;
in bng: Ln lt in theo tng ct j:= 1..n. Ti mi ct j ta t:
vi i := 0..j-1: cc[i,j] := cc[i,i];
vi i := j..m: cc[i,j] := cc[i,j-1]+cc[i-j,j];
Nhn kt qu: Sau khi in bng, gi tr cc[m, n] chnh l kt qu cn tm.
(*------------------------------------PHUONG AN 2: dung mang 2 chieu cc
cc[i,j] = Chia(i,j) - so cach chia i
phan thuong cho j hs
-------------------------------------*)
function Chia2(m,n: integer):longint;
var i,j: integer;
begin
cc[0,0] := 1;
for i := 1 to m do cc[i,0] := 0;
for j := 1 to n do
begin
for i := 0 to j-1 do cc[i,j] := cc[i,i];
for i := j to m do
cc[i,j] := cc[i,j-1]+cc[i-j,j];
end;
Chia2 := cc[m,n];
end;
Lm tt ln 2: Dng mng hai chiu chng ta ch c th tnh ton c vi d liu
nh. Bc ci tin sau y kh quan trng: chng ta dng mng mt chiu. Quan st k
quy trnh gn tr cho mng hai chiu theo tng ct chng ta d pht hin ra rng ct th
j c th c tnh ton t ct th j - 1. Nu gi c l mng mt chiu s dng, ta cho s
hc sinh tng dn bng cch ln lt tnh j bc, vi j := 1..n. Ti bc th j, c[i] chnh
l s cch chia i phn thng cho j hc sinh. Nh vy, ti bc th j ta c:
195
196
Pascal *)
uses crt;
const
MN = 70; {gioi han tren cua m va n }
nl = #13#10; {xuong dong }
bl = #32; {dau cach }
type
ml1 = array[0..MN] of longint;
ml2 = array[0..mn] of ml1;
var
cc: ml2; {cho phuong an 2 - mang 2 chieu }
m,n: integer;
c: ml1; {cho phuong an 3 mang 1 chieu }
nhip: longint absolute $0000:$046c;
{xac dinh nhip thoi gian }
t: longint; {ghi nhan nhip }
(*------------------------------------PHUONG AN 1: de quy
So cach Chia i phan thuong cho j hs
--------------------------------------*)
function Chia(i,j: integer):longint; t vit
(*------------------------------------PHUONG AN 2: dung mang 2 chieu cc
cc[i,j] = so cach chia i phan thuong
cho j hs
-------------------------------------*)
function Chia2(m,n: integer):longint; t vit
(*---------------------------------------PHUONG AN 3: dung mang 1 chieu c
Tai buoc j, c[i] = so cach chia i
phan thuong cho j hoc sinh.
-----------------------------------------*)
function Chia1(m,n: integer):longint; t vit
procedure test; t vit
BEGIN
Test;
END.
Quan st hot ng ca chng trnh bn s rt ra c ngha ca cc phng n
ci tin.
Ch thch
Bi ton trn cn c cch pht biu khc nh sau: Hy tnh s cch biu din s
t nhin m thnh tng ca n s t nhin sp theo trt t khng tng. Th d, vi
m = 7, n = 4 ta c:
7 = 7 + 0 + 0 + 0 = 6 + 1 + 0 + 0 = ...
197
// C#
using System;
using System.IO;
namespace SangTao1
{
/*-----------------------------------*
Chia thuong
* -----------------------------------*/
class ChiaThuong
{
static void Main()
{
Console.WriteLine(Chia(7, 4));
Console.WriteLine("\n Fini");
Console.ReadLine();
} // Main
static long Chia(int m, int n)
{
long[] c = new long[m+1];
Array.Clear(c, 0, c.Length);
c[0] = 1;
for (int j = 1; j <= n; ++j)
for (int i = j; i <= m; ++i)
c[i] += c[i - j];
return c[m];
}
} // ChiaThuong
} // SangTao1
Bi 7. 2. Palindrome
Olympic Quc t, nm 2000, Bc Kinh, Trung Quc.
Dy k t s c gi l i xng (palindrome) nu cc phn t cch u u
v cui ging nhau. Cho dy s to bi n k t gm cc ch ci hoa v thng
phn bit v cc ch s. Hy cho bit cn xo i t s t nht l bao nhiu k
t thu c mt dy i xng. Gi thit rng sau khi xo bt mt s k t
t s th cc k t cn li s t ng xch li st nhau.
D liu vo ghi trong tp vn bn PALIN.INP vi cu trc nh sau:
PALIN.INP
PALIN.OUT
Dng u tin l gi tr n, 1 n 1000.
9
4
Dng th hai l n k t ca dy vit lin
baeadbadb
nhau.
D liu ra ghi trong tp vn bn PALIN.OUT: s lng k t cn xa.
Th d, vi dy s gm 9 k t, s = 'baeadbadb' th cn xo t nht 4 k t, chng
hn, cc k t th 5, 7, 8 v 9 s thu c dy i xng chiu di 5 l baeab:
baeadbadb
baeab
bdadb
198
199
end;
j-1
b a e
i
i+1
b 1 1 1
a 0 1 1
[i,j-1]
[i,j]
e 0 0 1
[i+1,j-1]
[i+1,j]
a 0 0 0
d 0 0 0
b 0 0 0
a 0 0 0
d 0 0 0
b 0 0 0
Ga tr ca hm p(i,j) i vi dy baeadbadb
i,j=1..9
200
201
begin
for j := 1 to n do
begin
tr := 0;
d[j] := 1;
for i := j-1 downto 1 do
begin
t := d[i];
if s[i]= s[j] then d[i] := tr+2
else d[i] := max(d[i],d[i+1]);
tr := t;
end;
end;
writeln(nl,n-d[1]); {dap so}
end;
D nhin phng n dng mt mng mt chiu s c coi trng v tit kim c
min nh. Tuy nhin, tinh mt cht, bn s pht hin ra rng thi gian tnh ton theo
phng n ny khng t hn phng n dng hai mng mt chiu. Tht vy, tnh mi
phn t ta phi dng thm hai php gn, trong khi dng hai mng mt chiu ta ch phi
thm mt php gn cho mi phn t. Hn na, dng hai mng mt chiu thng trnh
c nhm ln, do nhiu ngi thng chn phng n ny.
Ton vn chng trnh vi ba phng n, quy, dng hai mng mt chiu v
dng mt mng mt chiu khi s nh sau.
(*
Pascal
*)
uses crt;
const mn = 51;
bl = #32; nl = #13#10;
fn = 'palin.inp';
gn = 'palin.out';
type mi1 = array[0..mn] of integer;
mi2 = array[0..mn] of mi1;
mc1 = array[0..mn] of char;
var n: integer; { Chieu dai xau }
f,g: text;
s: mc1; { xau can xu li }
d,v: mi1;
c: mi2;
procedure Doc; t vit
function Max(a,b: integer): integer; t vit
(*----------------------------------Phuong an de quy
------------------------------------*)
function rec(i,j: integer): integer; t vit
(*-----------------------------------Quy hoach dong voi mang 2 chieu c
-------------------------------------*)
function QHD2C: integer; t vit
(*--------------------------------Quy hoach dong voi 2 mang
1 chieu d, v
202
----------------------------------*)
function QHD2DV: integer; t vit
(*--------------------------------Quy hoach dong voi mang 1 chieu d
----------------------------------*)
function QHD1: integer; t vit
procedure Test;
begin
Doc;
writeln(nl,'Phuong an 1: De qui: ',n-rec(1,n));
writeln(nl,'Phuong an 2: Mang 2 chieu: ',n-QHD2C);
writeln(nl,'Phuong an 3: Hai Mang 1 chieu D, V: ',nQHD2DV);
writeln(nl,'Phuong an 4: Mang 1 chieu D: ',n-QHD1);
end;
BEGIN
Test;
readln;
END.
// C#
using System;
using System.IO;
namespace SangTaoT1
{
/*-----------------------------------*
Palindrome
* -----------------------------------*/
class Palin
{
static string fn = "palin.inp";
static string gn = "palin.out";
static string s;
static int n = 0;
static void Main()
{
Doc();
File.WriteAllText(gn,XuLi().ToString());
// Doc lai de kiem tra
Console.WriteLine("\n Input file " + fn);
Console.WriteLine(File.ReadAllText(fn));
Console.WriteLine("\n Output file " + gn);
Console.WriteLine(" So ki tu can xoa: " +
File.ReadAllText(gn));
Console.ReadLine();
}
static void Doc()
{
StreamReader f = File.OpenText(fn);
n = int.Parse((f.ReadLine()).Trim());
s = (f.ReadLine()).Trim();
203
f.Close();
}
static int XuLi()
{
int[] d = new int[n + 1];
int tr = 0;
int t = 0;
for (int j = 0; j < n; ++j)
{
tr = 0;
d[j] = 1;
for (int i = j - 1; i >= 0; --i)
{
t = d[i];
d[i] = (s[i]==s[j])?(tr+2)
:Max(d[i],d[i+1]);
tr = t;
}
}
return n - d[0];
}
static int Max(int a, int b)
{
return (a > b) ? a : b;
}
} // Palin
} // SangTao1
Bi 7.3. Cm hoa
Olympic Quc t nm 1999.
Cn cm ht k b hoa khc nhau vo n l xp thng hng sao cho b hoa c s
hiu nh c t trc b hoa c s hiu ln. Vi mi b hoa i ta bit gi tr
thm m khi cm b hoa vo l j l v[i, j].
Yu cu: Xc nh mt phng n cm hoa sao cho tng gi tr thm m l ln
nht.
D liu vo ghi trong tp vn bn HOA.INP:
Dng u tin l hai tr k v n.
T dng th hai tr i l cc gi tr v[i, j] trong khong 0..10, vi i = 1..k
v j = 1..n; 1 k n 100.
D liu ra ghi trong tp vn bn HOA.OUT: dng u tin l tng gi tr thm
m ca phng n cm hoa ti u. T dng th hai l dy k s hiu l c
chn cho mi b hoa.
Cc s liu vo v ra u l s t nhin v c ghi cch nhau bi du cch
trn mi dng.
Th d:
HOA.INP
HOA.OUT
4
1
9
7
6
1
1
2
6 4
4 7
6 10
3 10
2 7
2 3
24
1 3 4 6
204
6 10
B hoa 2 cm vo l 3;
B hoa 3 cm vo l 4;
B hoa 4 cm vo l 6.
Bi gii
Trc ht ta c d liu t tp HOA.INP vo cc bin k, n v v[i, j].
(*----------------------------------Doc du lieu
----------------------------------*)
procedure doc;
var i,j:byte;
begin
assign(f,fn);
reset(f);
readln (f,k,n);
for i := 1 to k do
for j := 1 to n do
read(f,v[i,j]);
close(f);
end;
Cc hng v bin c khai bo nh sau:
const
fn = 'hoa.inp'; {File du lieu vao }
gn = 'hoa.out'; {File du lieu ra }
mn = 101; {So luong toi da cac lo hoa: 100 }
bl = #32; {Dau cach }
nl = #13#10; {Xuong dong }
kk = (mn+7) div 8; {So bit danh dau cac lo hoa }
type
mb1 = array[0..mn] of byte; {mang byte 1 chieu }
mb2 = array[0..mn] of mb1; {mang byte 2 chieu }
ml1 = array[0..kk] of byte;
ml2 = array[0..mn] of ml1;
mi1 = array[0..mn] of integer;
var
n,k: byte; {n - so luong lo, k - so luong bo hoa }
v: mb2;
{v[i,j] - do tham my khi cam bo hoa i vao lo j }
L: ml2;
{cac mang danh dau lo hoa
bit(i) = 1: lo hoa duoc chon
bit(i) = 0: lo hoa roi}
T: mi1; {T[i,j]: tong so do tham mi
khi cam i bo hoa vao day j lo }
f,g: text; {files input va output }
205
j 1
i1
[i-1,j-1]
[i,j-1]
[i,j]?
- Nu T[i-1, j-1] + v[i, j] > T[i, j1] th ta phi thc hin hai thao tc:
206
Biu thc so snh cho bit khi cp nht mng T t bc th j - 1 qua bc th j ta phi
tnh t di ln, ngha l tnh dn theo chiu gim ca i:= j..1.
nh du cc l hoa ta dng mng L[0..MN] mi phn t L[i] li l mt dy s
byte. Nu dng mt bit cho mi l hoa th s byte cn dng nh du ti a MN l
hoa phi l:
kk = (MN+7) div 8
Vi MN = 101 ta tnh c
kk = (101+7) div 8 = 13
Khi cn nh du l hoa th j trong dy L[i] ta bt bit th j trong L[i]. Khi cn xem l
th j c c chn hay khng ta gi hm GetBit ly tr (0 hoc 1) ca bit j trong
dy bit L[i].
Ta ch ti hai biu thc sau:
(*
Pascal
*)
(*==================================
Hoa.pas: Quy hoach dong
===================================*)
uses crt ;
const
fn = 'hoa.inp'; {File du lieu vao }
gn = 'hoa.out'; {File du lieu ra }
mn = 101; {So luong toi da cac lo hoa: 100 }
bl = #32; {Dau cach }
nl = #13#10; {Xuong dong }
kk = (mn+7) div 8; {So bit danh dau cac lo hoa }
type
mb1 = array[0..mn] of byte; {mang byte 1 chieu }
207
208
// C#
using System;
using System.IO;
namespace SangTaoT1
{
/*-----------------------------------*
Cam hoa
* -----------------------------------*/
class CamHoa
{
209
210
}
}
// xet cac lo con lai
for (int j = k + 1; j <= n; ++j)
{
for (int i = k; i > 0; --i)
if (t[i - 1] + v[i, j] > t[i])
{
t[i] = t[i - 1] + v[i, j];
Lo[i - 1].CopyTo(Lo[i]);
Lo[i].BatBit(j);
}
}
Lo[k].CopyTo(d);
return t[k];
}
static void Doc()
{
int[] a = Array.ConvertAll((File.
ReadAllText(fn)).Split(
new char[] {'\0','\n','\t','\r',' '},
StringSplitOptions.RemoveEmptyEntries),
new Converter<String, int>(int.Parse));
k = a[0]; // so hoa
n = a[1]; // so lo
v = new int[k + 2, n + 2];
int i = 2;
for (int d = 1; d <= k; ++d)
for (int c = 1; c <= n; ++c)
v[d, c] = a[i++];
// dien 0 vao cac vi tri con lai
for (int j = 0; j <= n; ++j)
v[0, j] = v[k + 1, j] = 0;
}
// Hien thi du lieu
static void Show() t vit
} // CamHoa
// The hien 1 day lo
class DayLo
{
public const int bitnum = 32;
// so bit cho 1 bien int = 32 = 2^5
public int Size;
public uint[] Data;
public DayLo(int n) // day 0/1 gom n lo hoa
{
Size = (n + bitnum - 1) / bitnum;
Data = new uint[Size];
for (int i = 0; i < Size; ++i)
Data[i] = (uint)0;
}
// Gan tri 1 cho bit i trong day lo
// i >> 5 = i / 2^5 = i / 32
211
Bi ton
Cu lc b - Hc sinh gii Tin hc, H Ni, nm 2000
Cn b tr k nhm hc sinh vo k trong s n phng hc chuyn sao cho
nhm c s hiu nh c xp vo phng c s hiu nh hn phng cha nhm c
s hiu ln. Vi mi phng c nhn hc sinh, cc gh tha phi c chuyn ra
ht, nu thiu gh th phi ly t kho vo cho mi hc sinh mt gh. Bit s hc
sinh trong mi nhm v s gh trong mi phng. Hy chn phng n b tr sao
cho tng s ln chuyn gh ra v chuyn gh vo l t nht.
212
2
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
3
0
1
0
0
0
0
0
0
0
0
0
0
2
0
0
0
4
0
5
1
0
0
5
0
1
6
5
3
7
1
3
2
1
4
Bi gii
Thut gii quy hoch ng c trnh by di y mang tn Dijkstra, mt nh tin
hc li lc ngi H Lan. Bn cht ca thut ton l sa nh, chnh xc ra l sa trng
s ca mi nh.
Theo s gii cc bi ton quy hoch ng trc ht ta xy dng h thc cho bi
ton.
Gi p(i) l di ng ngn nht t nh s n nh i, 1 i n. Ta thy, hm p(i)
phi tho cc tnh cht sau:
a) p(s) = 0: ng ngn nht t nh xut pht s n chnh nh c chiu di 0.
b) Vi i s, mun n c nh i ta phi n c mt trong cc nh st trc
nh i. Nu j l mt nh st trc nh i, theo iu kin ca u bi ta phi c
a[j,i ] > 0
trong a[j, i] chnh l chiu di cung (j i).
Trong s cc nh j st trc nh i ta cn chn nh no?
213
214
for k := 1 to n do
begin
i := Min; { tim dinh i co trong so p[i] ->
min }
d[i] := 1; {danh dau dinh i la da xu li }
for j := 1 to n do
if d[j] = 0 then {dinh chua tham }
if a[i,j] > 0 then {co duong di i -> j }
if p[i] + a[i,j] < p[j] then
begin {sua dinh }
p[j] := p[i] + a[i,j];
before[j] := i;
end;
end;
end;
Thut ton cha hai vng for lng nhau do c phc tp l n2.
Sau khi hon thnh thut ton Dijkstra ta cn gi th tc Ket (kt) ghi li kt
qu theo yu cu ca u bi nh sau.
Vi mi nh i = 1..n ta cn ghi vo tp output chiu di ng i t s n i bao
gm gi tr p[i] v cc nh nm trn ng .
Ch rng nu p[i] nhn gi tr khi u tc l MAXWORD = 65535 th tc l
khng c ng i t s n i.
(*----------------------------------------Ket thuc thuat toan:ghi ket qua vao tep g
------------------------------------------*)
procedure Ket;
var i: byte;
begin
assign(g,gn); rewrite(g);
for i := 1 to n do
if (i=s) or (p[i] = MAXWORD) then
writeln(g,0)
else
begin
write(g,p[i],bl);
path(i);
writeln(g);
end;
close(g);
end;
V ngha, mng before cha cc con tr ngc t mi nh i n nh st trc
nh i trn ng i ngn nht, do ta phi ln ngc bng th tc quy path(i)
ghi vo tp g vt ca ng i theo trt t t s n i.
(*------------------------------------Giai trinh duong ngan nhat tu s den i.
Ghi vao file g
--------------------------------------*)
procedure path(i: byte);
begin
if i=0 then exit;
215
path(before[i]);
write(g,i,bl);
end;
(*
Pascal
*)
216
p[i] := MAXWORD;
before[i] := 0;
end;
p[s] := 0;
end;
(*--------------------------------------Giai trinh duong ngan nhat tu s den i.
Ghi vao tep g
----------------------------------------*)
procedure path(i: byte); t vit
(*--------- ---------------------Ket thuc thuat toan:
ghi ket qua vao file g
---------------------------------*)
procedure Ket; t vit
(*----------------------------------Trong so cac dinh chua xu ly,
chon dinh trong so min
-------------------------------------*)
function Min: byte;
var m, i: byte;
begin
m := 0;
for i := 1 to n do
if d[i]= 0 then {dinh i chua xu li }
if p[i] <= p[m] then m := i;
Min := m;
end;
(*---------------------------Thuat toan Dijkstra
------------------------------*)
procedure Dijkstra; t vit
BEGIN
Doc; Xem; Dijkstra; ket;
END.
Ta minh ho tin trnh hot ng ca thut ton Dijkstra qua
th d cho.
Sau khi c d liu t tp f=DIJ.INP ta c n = 7, s = 2.
th c 7 nh, nh xut pht l 2. Ma trn k a thu c
nh sau:
Khi tr
nh
befor
e
65535
65535
65535
65535
a
0
4
0
0
0
1
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
3
0
1
0
0
0
0
0
0
0
0
0
0
2
0
0
0
0
5
1
0
0
5
0
217
65535
65535
Bc lp k = 1
i = min = vi p[] = 0.
Cc nh cha x l v k vi nh s c sa trng s l 1, 3 v 7 (c du ).
V p[] + a[, 1] = 0 + 4 = 4 < p[1] = 65535 nn p[1] c sa thnh 4 v
before[1] c sa thnh .
V p[] + a[, 3] = 0 + 1 = 1 < p[3] = 65535 nn p[3] c sa thnh 1 v
before[3] c sa thnh .
V p[] + a[, 7] = 0 + 4 = 5 < p[7] = 65535 nn p[7] c sa thnh 5 v
before[7] c sa thnh .
nh
d
p
before
0
65535/4 0/2
1
0/1 0
0
0
65535/1 0/2
3
4
0
65535
0
5
0
65535
0
6
0
65535
0
0
65535/5 0/2
7
Bc lp k = 2
i = min = vi p[] = 1.
nh cha x l v k vi nh s c sa trng s l nh 7.
V p[] + a[, 7] = 1 + 1 = 2 < p[7] = 5 nn p[7] c sa thnh 2 v
before[7] c sa thnh .
nh
1
4
5
6
7
d
0
0/1
0/1
0
0
0
0
p
65535/4
0
65535/1
65535
65535
65535
65535/5/2
before
0/2
0
0/2
0
0
0
0/2/3
Bc lp k = 3
i = min = 7 vi p[] = 1
nh cha x l v k vi nh 7 s c sa trng s l nh 4.
V p[] + a[, 4] = 2 + 1 = 3 < p[4] = 65535 nn p[4] c sa thnh 3 v
before[4] c sa thnh .
nh
d
p
before
1
0
65535/4
0/2
0/1 0
0
0/1 65535/1
0/2
0
65535/3
0/7
4
5
0
65535
0
6
0
65535
0
218
i = min = 4 vi p[] = 3.
nh cha x l v k vi nh s c sa trng s l nh 6.
V p[] + a[, 6] = 3 + 2 = 5 < p[6] = 65535 nn p[6] c sa thnh 5 v
before[6] c sa thnh .
nh
before
65535/4
0/2
0/1
0/1
65535/1
0/2
0/1
65535/3
0/7
65535
65535/5
0/4
0/1
65535/5/2
0/2/3
Bc lp k = 5
i = min = vi p[] = 4.
Khng c nh cha x l no k vi nh .
nh
before
0/1
65535/4
0/2
0/1
0/1
65535/1
0/2
0/1
65535/3
0/7
65535
65535/5
0/4
0/1
65535/5/2
0/2/3
Bc lp k = 6
i = min = vi p[] = 5.
Khng c nh cha x l no k vi nh . Ch rng nh 7 k vi nh
nhng nh 7 ny x l ri.
nh
before
0/1
65535/4
0/2
0/1
0/1
65535/1
0/2
0/1
65535/3
0/7
65535
0/1
65535/5
0/4
0/1
65535/5/2
0/2/3
219
ng i ngn nht t nh s = 2 n nh t = 4:
nh d
p
before
V p[4] = 3 nn di ng i l 3.
1
1 4
2
gii trnh vt ca ng i t 2 n 4 ta da
2
1 0
0
vo mng before[1..7] nh sau:
1 1
2
V before[4] = 7, tc l trc khi n nh 4 phi 3
qua nh 7 nn ta c
4
1 3
7
74
5
0 65535 0
V before[7] = 3, tc l trc khi n nh 7 phi
6
1 5
4
qua nh 3 nn ta c
7
1 2
3
374
V before[3] = 2, tc l trc khi n nh 3 phi qua nh 2 nn ta c
2374
Kt qu ny c ghi dng th t ca tp DIJ.OUT nh sau:
3 2 3 7 4
trong s u tin 3 cho bit chiu di ng i, dy s cn li gii trnh vt ca
ng i t nh 2 n nh 4.
ng i ngn nht t nh s = 2 n nh t = 5:
V p[5] = 32767 ng vi gi tr dng v cng khi tr lc u nn khng c
ng i t nh 2 n nh 5.
Ta ghi kt qu 0 ti dng 5 ca tp DIJ.OUT.
ng i ngn nht t nh s = 2 n nh t = 2:
V s = t nn ta coi nh khng c ng i t nh 2 n nh 2.
Ta ghi kt qu 0 ti dng 5 ca tp DIJ.OUT.
Cc dng khc ca bi ton Dijkstra
Lu rng ma trn k c th cha cc gi tr thc, tuy nhin cn gi thit rng mi
gi tr trong ma trn k phi l cc s khng m. Vi cc s m bi ton s phc tp
hn.
P1. Nu th cho l v hng ta gii nh trn, ch lu n tnh i xng khi
c d liu vo ma trn k a.
P2. Nu bi ch yu cu tm mt ng i t nh s n nh t ta thc hin cc
bc sau:
1. c d liu.
2. Gi thut ton Dijkstra.
3. Ghi kt qu p[t] v gii trnh mt ng theo thut ton path(t).
// C#
using System;
using System.IO;
using System.Collections;
namespace SangTaoT1
{
/*-----------------------------------*
Thuat toan Dijkstra
* Tim moi duong ngan nhat tu mot dinh
* den moi dinh con lai
* -----------------------------------*/
class Dijkstra
{
const string fn = "Dij.inp";
const string gn = "Dij.out";
static int n = 0; // so dinh
static int s = 0; // dinh xuat phat
// c[i,j] ma tran ke cho biet
// do dai cung (i,j)
static int[,] c;
static int[] d; // danh dau dinh
static int[] t; // tro truoc
static int[] p; // trong so dinh
static void Main()
{
Run();
Console.ReadLine();
} // Main
static void Run()
{
Doc(); Show(); Dij();
Ghi(); Test();
Console.WriteLine("\n Fini");
Console.ReadLine();
}
// Kiem tra lai tep output
static void Test() t vit
static void Ghi()
{
StreamWriter g = File.CreateText(gn);
for (int i = 1; i <= n; ++i)
if (i == s || p[i] == int.MaxValue)
g.WriteLine(0);
else
{
g.Write(p[i] + " ");
int u = InvPath(i);
for (int j = u; j > 0; --j)
g.Write(d[j] + " ");
g.WriteLine();
}
g.Close();
}
// Lan nguoc duong di
// tu dinh v den dinh s
// ghi tam vao mang d
static int InvPath(int v)
{
int i = 0;
do
{
d[++i] = v;
v = t[v];
} while (v != 0);
return i;
220
}
static void Dij()
{
for (int i = 0; i <= n; ++i)
{ //d: danh dau dinh, t: tro truoc
d[i] = t[i] = 0;
p[i] = int.MaxValue; // Trong so
}
p[s] = 0;// s: dinh xuat phat
for (int i = 1; i < n; ++i)
{
int u = Minp();// u: dinh trong so min
d[u] = 1; // danh dau dinh da xet
// sua lai nhan dinh
for (int v = 1; v <= n; ++v)
if (d[v] == 0) // dinh chua xet
if (c[u, v] > 0) // co cung(u,v)
if (p[u] + c[u, v] < p[v])
{ // sua lai nhan dinh v
p[v] = p[u] + c[u, v];
// chon cach di tu u -> v
t[v] = u;
}
}
}
// Tim trong so cac dinh chua
// xu li mot dinh j co p min
static int Minp()
{
int jmin = 0;
for (int i = 1; i <= n; ++i)
if (d[i] == 0) // dinh i chua xet
if (p[i] < p[jmin]) jmin = i;
return jmin;
}
static void Doc()
{
int[] a = Array.ConvertAll((File.
ReadAllText(fn)).Split(
new char[] {'\0','\n','\t','\r',' '},
StringSplitOptions.RemoveEmptyEntries),
new Converter<String, int>(int.Parse));
n = a[0]; // so dinh
s = a[1]; // dinh xuat phat
c = new int[n + 1, n + 1];
d = new int[n + 1];
t = new int[n + 1];
p = new int[n + 1];
int k = 2;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
c[i, j] = a[k++];
}
221
// Hien thi
static void
// hien thi
static void
} // Dijkstra
} // SangTao1
du lieu
Show() t vit
mang
Print(int[] a, int n) t vit
222
223
CHNG 8
SUY NGM
Bi 8.1. Lt nn
Ngi ta cn lt kn mt nn nh hnh vung cnh di n = 2k, (k l mt s t nhin
trong khong 1..6) khuyt mt phn t ti gc trn phi bng nhng vin gch mu
hnh thc th (ch L) to bi 3 vung n v nh trong hnh 2b. Hai vin gch k
cnh nhau d ch 1 n v di phi c mu khc nhau. Hy cho bit mt cch lt vi
s mu t nht.
a) Nn nh
b) Gch lt
Hnh 2
D liu vo: tp vn bn NEN.INP cha s t nhin n.
D liu ra: tp vn bn NEN.OUT. Dng u tin l hai s t nhin m biu th
s vin gch v c l s mu cn dng cho vic lt nn. Tip n l mt phng
n lt nn tm c, trong mi vin gch lt c to bi ba ch s ging
nhau th hin mu ca vin gch . Cc s trn mi dng cch nhau qua du
cch.
224
Th d, vi n = 8 ta c mt cch lt nn nh
sau:
NEN.INP
NEN.OUT
16 3
3 3 1
3 2 2
1 2 3
1 1 3
3 3 1
3 2 1
1 2 2
1 1 3
1 1
2 1
3 3
1
1
3
2
2
1
3
3
2
3
1
1
3
3
2
1
1
2
2
3
1
1
3
3
3
3
1
1
3 2
225
Hnh 6
Ta biu din nn nh hnh vung qua mt mng hai chiu a vi cc dng c m s 1..n
t trn xung v cc ct c m s t 1..n t tri qua phi. Khi vin gch gc di tri s
c to [n, 1]. Sau khi c d liu nhn gi tr n, ta gn tr ban u cho 4 vin gch gc
di tri nh sau:
a[n-1,1]
:=
1; a[n-1,2]
a[n,1]
:=
1; a[n,2]
:=
:=
2;
1;
A
nv+1
...
n1
...
A
nv+
1
...
n1
...
226
nv+
1
...
n1
...
nv+1
...
n1
1 2 ... v
Hnh 10. Lt A ln trn thu c D
lt phi hnh vung A ta cng chuyn dn tng phn t trong cc dng, t dng
n v + 1 n dng cui cng, dng th n n v tr mi. Tuy nhin cn lu thay i tr
mu t 1 sang mu 3 v ngc li. Thao tc ny c thc hin qua php gn 4 c,
trong c l mu ca gc. Nu c = 2 th 4 2 = 2, tc l mu 2 khng thay i (h. 9).
227
Bnh lun
Thut gii s dng hai php bin hnh c bn trong chng trnh ph thng l php
di hnh (tnh tin) v i xng qua trc. Vic hon i tr 1 v 3 cho nhau l mt
tng thng minh. Mi trong bng c in ng mt ln do phc tp tnh
ton ca thut ton l n2, trong khi cc bi gii khc u phi s dng cc php d tm
xc nh mu t v gi quy nn thng tn km v min nh v thi gian hn
nhiu ln.
(*
Pascal
*)
(****************************
LATNEN lat nen nha
hinh vuong khuyet goc bang
cac vien gach mau hinh L
*****************************)
const
fn = 'NEN.INP'; {input file}
gn = 'NEN.OUT'; {output file}
bl = #32; {dau cach}
mn = 65; {kich thuoc toi da cua n}
var {n chieu dai canh nen nha}
f,g: text;
a: array[0..mn,0..mn] of byte; {nen nha}
228
// C#
using System;
using System.IO;
namespace SangTao1
{
/*----------------*
Lat nen
* ----------------*/
class LatNen
{
const string fn = "Nen.inp";
const string gn = "Nen.out";
static int n = 0; // canh nen nha
static int[,] c; // nen nha
static void Main()
{
Run();
Console.ReadLine();
} // Main
static void Run()
{
Doc(); Lat(); Ghi();
Test();
Console.WriteLine("\n Fini");
Console.ReadLine();
}
229
230
231
c[i,2*k-j-1] = 4-c[i,j];
}
// dich ma tran kXk theo huong Dong-Bac
static void DichCheo(int k)
{
for (int i = n - k; i < n; ++i)
for (int j = 0; j < k; ++j)
c[i - k, j + k] = c[i, j];
}
static void Doc()
{
n = int.Parse(File.ReadAllText(fn).Trim());
Console.WriteLine("\n Da doc n = " + n);
}
} // LatLen
} // SangTao1
Bi gii
Thut gii ca bn Vit Hng (H Ty, 2002) cho php m rng gii hn ca n n hng
chc vn v nu bn mun, c th tip tc m rng n hng triu.
tng chnh ca Vit Hng nm cng thc: 2 5 = 10 (hai ln nm l mi).
Tht vy, ta bit:
n! = 1.2.3...n
Cc ch s cui cng bng 0 ca n giai tha c sinh ra khi v ch khi trong khai
trin ra tha s nguyn t ca tch trn c cha cc cp tha s 2 v 5. Vy th trc ht
ta m s lng cc tha s 2, k hiu l d2 v s lng cc tha s 5, k hiu l d5.
Th d, vi n = 15 ta c dng khai trin ra tha s nguyn t ca n giai tha nh
sau:
n! = 1.2.3.(2.2).5.(2.3).7.(2.2.2).9.(2.5).11. (2.2.3).13.(2.7).(3.5)
Do d2 = 11 v d5 = 3. Vy ta c ba cp 2.5 = 10 v s m di ra ca tha s 2
so vi tha s 5 s l d2 d5 = 11 3 = 8. Khi , kt qu s l:
ch s cui cng khc 0 ca 15! = ch s cui cng ca
k.2d2-d5
Trong k l tch ca cc tha s cn li.
D thy vi mi n, ta lun c d2 d5 v c hai s lin tip th c mt s chn (chia
ht cho 2), cn nm s lin tip mi c mt s chia ht cho 5.
Vic cn li l ly tch k ca cc s cn li. V tch ny khng bao gi tn cng
bng 0 cho nn ta ch cn gi li mt ch s cui cng bng cch ly mod 10.
tnh ch s tn cng ca 2m vi m = d2 d5 > 0 ta n tnh tun hon ca
n, c th l ta ch cn tnh ch s tn cng ca 2(m mod 4) vi cc trng hp:
m mod 4 = 0, 1, 2 v 3.
232
Bnh lun
rng:
14! = 87178291200, c ch s cui cng khc 0 l 2
15! = 1307674368000, c ch s cui cng khc 0 l 8.
Nu tnh 15! m bn ch ly mt ch s cui khc 0 ca cc php tnh trung gian
th sau khi tnh ch s cui ca 14! bn s nhn c 2 v cui cng l:
(2*15) mod 10 = 30 mod 10 = 3.
Kt qu ny l sai v ch s cui khc 0 ca 15! l 8.
Chng trnh sau y cha th tc find tm ch s cui cng khc 0 ca n! vi n
trong khong 1..65535.
Ta thc hin mt ci tin nh nh sau. Thay v m s lng cc tha s 2 (d2) v
tha s 5 (d5) sau lm php tr d2 d5, ta m lun mt ln hiu s ny v ghi vo
bin m. C th l vi mi gi tr i = 2..n ta m s lng cc tha s 2 trc, sau tr
i s lng cc tha s 5.
(*
Pascal
*)
233
d := 0;
for i := 2 to n do
begin
c := i;
while c mod 2 = 0 do
begin
m := m+1; c := c div 2;
end;
while c mod 5 = 0 do
begin
m := m-1; c := c div 5;
end;
k := (k*(c mod 10)) mod 10;
end;
case (m mod 4) of
0: c := 6;
1: c := 2;
2: c := 4;
3: c := 8;
end;
find := (k*c) mod 10;
end;
procedure run;
var n: longint;
begin
writeln('--------------------');
repeat
write(' Nap N (Muon dung chuong trinh, bam 0 ):
');
read(n);
if n = 0 then halt;
writeln(' find(',n,') = ',find(n));
until false;
end;
BEGIN
run;
END.
K thut gn trc
Bn c th thay lnh Case trong vic tnh ch s tn cng ca 2m bng cc thao tc
sau:
1. Khai bo v gn trc tr cho mng LuyThua
const LuyThua: array[0..3] of word = (6,2,4,8);
ngha ca dng lnh trn: khai bo mt mng kiu word vi bn phn t c ch
s bin thin t 0..3 v gn trc tr cho mng ny l:
LuyThua[0] := = 6; {= 24 mod 10}
LuyThua[1] = 2; {= 21 mod 10}
LuyThua[2] = 4; {= 22 mod 10}
LuyThua[3] = 8; {= 23 mod 10}
234
// C#
using System;
namespace Tap1
{
/*-----------------------------*
Chu so cuoi khac 0 cua n!
* -----------------------------*/
class ChuSoCuoi
{
static void Main()
{
Test(200);
} // Main
static void Test(int n)
235
{
for (int i = 1; i < n; ++i)
{
Console.Write("\n Chu so cuoi khac 0 cua " +
i + "! = " + Find(i)+". ");
Console.Write("Bam exit de thoat: ");
if (Console.ReadLine() == "exit") break;
}
}
static int Find(int n)
{
if (n < 2) return 1;
int m = 0;
long k = 1;
int c = 0;
int[] mu = { 6, 2, 4, 8};
for (int i = 2; i <= n; ++i)
{
c = i;
while (c % 2 == 0)
{
++m; c /= 2;
}
while (c % 5 == 0)
{
--m; c /= 5;
}
k = (k * (c % 10)) % 10;
}
return (int)((k * mu[m % 4]) % 10);
}
} // ChuSoCuoi
} // SangTao1
Bi tp lm thm
Bi T1. Cho bit N! tn cng vi bao nhiu ch s 0. Th d, 15! tn cng vi 3 ch s
0, v 15! = 1307674368000.
Gi Nu p l mt s nguyn t v pK l nhn t trong dng phn tch N! ra
tha s nguyn t th k c tnh bng tng ca cc thng nguyn trong
php chia lin tip ca N cho p.
Th d, vi N = 15, p = 2 v k hiu : l php chia nguyn, ta tnh c
15 : 2 = 7; 7 : 2 = 3; 3 : 2 = 1; 1 : 2 = 0. Do k = 7+3+1+0 = 11.
Vi N=15, p = 5 ta tnh c 15 : 5 = 3; 3 : 5 = 0. Do k = 3+0 = 3.
Nh vy 15! = 211.53.C.
Chng minh iu ny kh d, bn ch cn vit dy 1.2N thnh cc dng, mi
dng p tha s
1
p+1
2p
k1p = N!
236
Hnh 4
Th d, vi ma trn 5 9 cha d liu nh hnh 4 th hnh ch nht ti i, tm gi
l ABCD, c din tch l 15 v c to im A l (dng 2, ct 3) v im C l (dng
4, ct 7) nh trong hnh 4.
CNMAX.INP
CNMAX.OUT
9
100000000
111111110
001111100
001111100
000000000
15
2 3
4 7
237
ng M im m s t 1 n M. Mi im c t mt mu th hin cao ca
im . Yu cu: xc nh hnh ch nht ABCD cha nhiu im ng mu nht.
D liu vo: Tp vn bn CNMAX.INP.
- Dng u tin: s t nhin M, 3 M 70.
- Tip n l cc dng di bng nhau th hin mt xu gm M k t l cc
ch ci a..z vit lin nhau. Mi k t biu din cho mt mu th hin cao
ca im tng ng trn mnh bn hnh tinh Vega. Hai k t khc nhau
th hin hai cao khc nhau. Hai im cng cao c biu din vi
cng mt k t.
- S dng ca tp input c th ln ti 60 nghn.
Th d:
CNMAX.INP
20
bcccddddeabcvvvvvvvb
bbbbbccccccccccbbbbb
vvvvvcccccccccccccbb
vvcccccccccccccbbbbb
pppppccccccccccabbbb
pppppcccccccccczzzzz
ssccccccccccccczzzzz
sssssccccccccccccczz
hhhhhcccccccccczzzzz
uuuuuuuuczzzzzzzzzzz
CNMAX.OUT
80
2 6
9 15
Bi gii
Do khng th c ton b d liu t tp CMAX.INP vo mt mng x l nn
chng ta s c mi ln mt dng vo bin kiu xu k t (string) y. V hnh ch nht
ABCD cn tm cha cng mt loi k t cho nn cc dng ca hnh s lin thng nhau.
pht hin tnh lin thng chng ta cn dng thm mt bin kiu xu k t x lu
dng c v x l bc trc. Tm li l ta cn x l ng thi hai dng: x l dng
trc v y l dng ang xt.
Nu xt cc ct trong hnh ch nht cn tm ta thy chng phi cha cng mt loi
k t. Ta dng mt mng h vi ngha phn t h[i] ca mng cho bit tnh t v tr th i
ca dng y tr ln c bao nhiu k t ging nhau (v ging vi k t y[i]). Ta gi h[i] l
cao ca ct i v mng h khi s c gi l cao ca dng ang xt.
Th d, mng tch lu cao ca dng th 5 trong th d cho s l:
h = (1,1,1,1,1,4,4,4,4,4,4,5,4,4,4,1,2,2,4,5)
A
238
Bit cao, vi hai dng x v y chng ta d dng tnh c din tch ca mi hnh
ch nht ABCD cha phn t y[i] trn cnh DC. Tht vy, gi s ta ang xt k t th i
= 8 trn dng th 5 nh ni phn trn. Ta c h[8] = h[7] = h[6] = 4; h[9] = h[10] =
h[11] = 4; h[12] = 5; h[13] = h[14] = h[15] = 4; h[16] = 1,... Vy th, khi ta i t i v hai
pha, tri v phi, nu gp cc k t ging k t y[i] cn cao th khng nh hn h[i] ta
s thu c hnh ch nht ln nht cha k t y[i].
Vi dng th 5 l y ang xt, ta c:
x = 'vvcccccccccccccbbbbb'; {dng thu 4 }
y = 'pppppccccccccccabbbb'; {dng thu 5 }
1
10
11
12
13
14
15
16
17
18
19
20
4 x
5 y
dng
239
1;
Mt vi ch gii
1.
2.
3.
4.
5.
240
5. ng tp CNMAX.INP.
6. Thng bo kt qu.
procedure Run;
var i,c1,c2: byte;
dt: longint;
begin
assign(f,fn); reset(f); readln(f,m);
d := 0;
{Khoi tri cho dong dau tien}
x := BL;
for i := 1 to m do x := x + BL;
{Khoi tri cho chieu cao}
fillchar(h,sizeof(h),0);
while not eof(f) do
begin
readln(f,y);
inc(d);
{Chinh do cao}
for i :=
1 to m do
if y[i] = x[i] then inc(h[i]) else h[i] :=
1;
for i :=
1 to m do
begin
dt :=
DienTich(i,c1,c2);
if dt > dtmax then
begin
dtmax
:=
dt;
Axmax := d-h[i]+1; Aymax := c1;
Cxmax := d; Cymax := c2;
end;
end;
x := y;
end;
close(f);
Ket; {ghi ket qua}
end;
(*
Pascal
*)
(******************************************
CNMAX Dien tich hinh chu nhat
toi dai
******************************************)
uses crt;
const
fn = 'CNMAX.INP'; {Ten tep chua du lieu vao}
gn = 'CNMAX.OUT'; {Ten tep chua du lieu ra}
MN = 80; {chieu rong van ban}
241
//
C#
using System;
using System.IO;
namespace SangTao1
{
/*-----------------------------*
Chu nhat toi dai
* -----------------------------*/
class ChuNhatMax
{
static string fn = "cnmax.inp"; // input file
static string gn = "cnmax.out"; // output file
static string x;// dong tren
static string y;// dong duoi
static int m = 0; // chieu dai moi dong
static int[] d; // cao do
static int dong = 0; // dem dong
static int smax = 0; // dien tich max
static int ad = 0; // toa do dong cua dinh A
static int ac = 0; // toa do cot cua dinh A
242
243
}
}
}
// quet tu k qua phai
static int Phai(int k)
{
for (int i = k + 1; i < m; ++i)
if (d[i] < d[k]) return i - 1;
return m - 1;
}
// quet tu k qua trai
static int Trai(int k)
{
for (int i = k - 1; i >= 0; --i)
if (d[i] < d[k]) return i + 1;
return 1;
}
} // ChuNhatMac
} // SangTao1
ng dng
Bi ton tm hnh ch nht ti i thng dng trong lnh vc ho v x l nh.
Di y lit k vi ng dng in hnh.
1. Trong khi v bn ta thng phi tm mt hnh ch nht ti i trong mt
vng, chng hn lnh th ca mt quc gia c th vit cc k t vo nh
tn quc gia, tn chu lc.
2. Trong hnh hc phn hnh (fractal) ta thng phi tm mt s hnh vung hoc
ch nht ti i tho mn mt s tiu chun cho trc lm mu.
Trong bi ny, trnh by vn c n gin chng ta thay mi im bng
mt k t.
Bi tp lm thm
Bi T1. Vi mi k t c cho trc hy tm trong tp CNMAX.INP mt hnh ch
nht ti i cha ton k t c.
Bi T2. Vi cp gi tr (k, c) cho trc hy tm hnh ch nht ti i cha cng
mt loi k t v ng thi cha im nm trn dng k, ct c ca tp
CNMAX.INP.
Bi 8.4. Ma phng
Ma phng l nhng bng s hnh vung trong mi dng, mi ct v mi
ng cho u cng tho mt s tnh cht no . Cc nh thin vn c Trung
Hoa cho rng mi tinh t trn bu tri u ng vi mt ma phng. Nhiu nh
ton hc c Ai Cp, n v sau ny cc nh ton hc phng Ty pht
hin nhng tnh cht kh l th ca cc loi ma phng. Trong bi ny ta gii
hn khi nim ma phng theo ngha sau.
244
16
13
11
10
12
14
15
(a)
(b)
(a) ma phng bc 3, c s S3 = 15
(b) ma phng bc 4, c s S4 = 34
Bi gii
Ta d dng tnh c c s ca ma phng bc n qua nhn xt: tng ca mt ct
(dng) chnh l tng ca ton b cc s nm trong bng chia cho s ct (s dng):
Sn = (1 + 2 + ... + n2)/n = n(n2 + 1)/2.
Theo cc th d trn ta c:
c s ca ma phng bc 3: S3 = 3(9 + 1)/2 = 15.
c s ca ma phng bc 4: S4 = 4(16 + 1)/2 = 34.
Nh vy, trong ma phng bc 3, tng ca cc s nm trn cng hng, cng ct
hoc cng ng cho u l 15. Trong ma phng bc 4, tng ny l 34.
Tnh cht trn khng thay i nu ta in ln lt cc s hng ca mt cp s cng
vo ma phng.
Ngoi bc n = 2, vi mi s t nhin n 1 u tn ti ma phng vi nhiu cch
b tr khc nhau. Chng ta s tm hiu hai thut ton d ci t.
Vi mi n cho trc ta xt tnh chn l ca n. Nu n l ta gi th tc MPL (ma phng
bc l), ngc li ta gi th tc MPC (ma phng bc chn).
(*------------------------------Ma phuong
--------------------------------*)
procedure MP(bac: word);
begin
n := bac;
if n = 2 then exit;
if Odd(n) then MPL else MPC;
Test;
end;
Trong n l bin tng th cha bc ca ma phng cn xy dng.
245
k+1
246
k+1
k+1
ng-Nam
C
ng
B
k+1
k+1
k
C
Nam
C
ng
247
fillchar(M, sizeof(M),0);
{Buoc 2: Xac dinh o xuat phat}
i := n;
j := n div 2 + 1;
{Buoc 3: Dien so}
for k := 1 to n*n do
begin
{3.1. Dien o (i,j)}
M[i,j] := k;
{3.2 Xac dinh vi tri ii,jj
cho so tiep theo (k+1)}
if (i=n) and (j=n) then
{3.2.1.Tinh huong Dong-Nam:Den tren}
begin
ii := n-1; jj := n;
end
else
begin {3.2.2 va 3.2.3.}
ii := i mod n + 1;
jj := j mod n + 1;
end;
if M[ii,jj]<>0 {o da dien} then
begin
{3.2.4. Dung do: Den tren}
ii := i-1; jj := j;
end;
i := ii; j := jj;
end;
end;
Th tc MPC(n): Ma phng bc chn
Bc 1. Khi tr: in cc s t 1 n n2 vo bng theo trt t t trn xung di,
t tri sang phi. Th d, vi n = 4, M c khi tr nh sau:
1
10
11
12
13
14
15
16
248
M[i,n-j+1] M[n-i+1,j]
'D' - thc hin php i xng theo trc dc: i ch cp phn t:
M[i,j] M[i,n-j+1]
- 'N' - thc hin php i xng theo trc ngang: i ch cp phn t:
M[i,j] M[n-i+1,j]
- 'B' - khng lm g.
Xu mu s c to nh sau:
2.1. Khi tr xu rng s[0] := #0;
2.2. Tnh k := n div 2;
2.3. Np (k div 2) k t 'T' cho s.
for i := 1 to (k div 2) do
s := s+TT;
2.4. Nu k l np thm hai k t 'DN' cho s:
if Odd(k) then s := s+DD+NN;
2.5. in thm cc k t 'B' cho k k t trong s.
for i := length(s)+1 to k do s := s+BB;
trong cc hng TT, DD, NN v BB c khai bo nh sau
const
TT = 'T'; {doi xung Tam}
DD = 'D'; {doi xung Doc}
NN = 'N'; {doi xung Ngang}
BB = 'B'; {Bo qua}
Cc th d to xu mu s:
- Vi n = 4 ta c k = n div 2 = 2 (chn), k div 2 = 1, do s='TB'
- Vi n = 6 ta c k = n div 2 = 3 (l), k div 2 = 1, do s='TDN'
- Vi n = 18 ta c k = n div 2 = 9 (l), k div 2 = 4, do s='TTTTDNBBB'
Th tc khi tr cho ma phng bc chn s nh sau:
(*----------------------------------------Khoi tri cho ma phuong bac chan
------------------------------------------*)
procedure InitMPC;
var i,j: word;
begin
{Buoc 1. Khoi tri}
for i := 1 to n do
for j := 1 to n do
M[i,j] := Num(i,j);
{Buoc 2: Tao xau mau}
s[0] := #0; {Khoi tri xau rong}
k := n div 2;
{Nap (k div 2) ki tu T}
for i := 1 to (k div 2) do s := s+TT;
{Nap them 2 ki tu D va N neu k le}
if Odd(k) then s := s+DD+NN;
{Bu cac ki tu B cho du k ki tu}
for i := length(s)+1 to k do s := s+BB;
end;
-
249
250
M[n-i+1,n-j+1] := Num(i,j);
M[n-i+1,j] := Num(i,n-j+1);
M[i,n-j+1] := Num(n-i+1,j);
end;
(*-------------------------------------Doi xung doc
--------------------------------------*)
procedure Doc(i,j: word);
begin
M[i,j] := Num(i,n-j+1);
M[i,n-j+1] := Num(i,j);
end;
(*----------------------Doi xung ngang
------------------------*)
procedure Ngang(i,j: word);
begin
M[i,j] := Num(n-i+1,j);
M[n-i+1,j] := Num(i,j);
end;
Mi ln x l xong mt dng ta cn quay xu mu s thm mt v tr theo chiu kim
ng h, k t cui xu c a v u xu, cc k t khc c dch qua phi mt v
tr.
Th d v quay xu mu s: Vi n = 18 ta c:
s = 'TTTTDNBBB'
sau ln quay th nht ta thu c
s = 'BTTTTDNBB'
sau ln quay th hai ta thu c
s = 'BBTTTTDNB'
251
252
(* Pascal
*)
n,k: word;
s: string;
(*-------------------------------Hien thi va kiem tra ket qua
----------------------------------*)
procedure Test; t vit
(*-----------------------------------So nam tren hang i, cot j
-------------------------------------*)
function Num(i,j: word):word;
begin
Num := (i-1)*n+j;
end;
(*------------------------------------Lay doi xung qua tam (2 so)
--------------------------------------*)
procedure Tam(i,j: word); t vit
(*-------------------------------------Doi xung doc
--------------------------------------*)
procedure Doc(i,j: word); t vit
begin
M[i,j] := Num(i,n-j+1);
M[i,n-j+1] := Num(i,j);
end;
(*-------------------------------------Doi xung ngang
---------------------------------------*)
procedure Ngang(i,j: word); t vit
(*-------------------------Quay xau mau s 1 vi tri
---------------------------*)
procedure QuayXauMau; t vit
(*----------------------------------------Khoi tri cho ma phuong bac chan
------------------------------------------*)
procedure InitMPC; t vit
procedure XuLyDong(i: word); t vit
(*--------------------------Ma phuong bac chan
----------------------------*)
procedure MPC; t vit
(*--------------------------------Ma phuong bac le
----------------------------------*)
procedure MPL; t vit
(*------------------------------Ma phuong
--------------------------------*)
procedure MP(bac: word); t vit
(*-------------------------------Test cac ma phuong bac 1..20
----------------------------------*)
253
procedure Run;
var i: word;
begin
clrscr;
for i := 1 to 20 do MP(i);
end;
BEGIN
Run;
END.
// C#
using System;
namespace SangTao1
{
class maphuong
{
const int mn = 50;
static int[,] a = new int[mn, mn]; // Ma phuong
static char[] s = new char[mn]; // Xau mau
static void Main(string[] args)
{
for (int n = 1; n <= 20; ++n)
{ MaPhuong(n); Console.ReadLine();}
}
static void MaPhuong(int n)
{
if (n == 2)
Console.WriteLine("\n Khong ton tai "+
"Ma phuong bac 2");
else if (n % 2 == 1) MaPhuongLe(n);
else MaPhuongChan(n);
}
static void MaPhuongLe(int n)
{
Array.Clear(a,0,a.Length);
int i = n - 1;
int j = n / 2;
int nn = n * n;
a[i, j] = 1;
for (int k = 2; k <= nn; ++k)
{ Next(ref i, ref j, n); a[i, j] = k;}
Test(n); Print(n);
}
// Ma phuong le: Tim o dien tiep
static void Next(ref int i, ref int j, int n)
{
int ic = i; int jc = j;
i = (i + 1) % n; j = (j + 1) % n;
if (i + j == 0)
{ i = n - 2; j = n - 1;}
if (a[i, j] > 0)
{ i = ic - 1; j = jc;}
}
254
255
256
257
{
Console.WriteLine();
for (int j = 0; j < n; ++j)
Console.Write("{0} ", a[i, j]);
}
}
} // MaPhuong
}// SangTao1
Cc bi ton Thp H Ni
Bi 8.5. Thp H Ni c
258
259
assign(f,'hanoi.out');
rewrite(f);
th sau mi lnh
write(f,);
s ghi d liu vo tp hanoi.out trn a.
Chng trnh hon chnh di y s ghi kt qu vo tp vn bn hanoi.out
c m trn a. Trc khi ghi chnh thc, bn hy chy th chng trnh vi lnh m
tp c tn rng kim tra kt qu trn mn hnh. Sau khi thy ng , bn hy vit tn
tp c th lu kt qu vo a.
Chng trnh s dng bin m d nhm m s bc chuyn.
(*
Pascal
*)
uses crt;
var d: longint;
f: text;
procedure Hn(n,a,b: byte);
begin
if n = 0 then exit;
Hn(n-1,a,6-a-b);
inc(d);
writeln(f,d,'. ',a,' -> ',b);
Hn(n-1,6-a-b,b);
end;
procedure runHn(n: byte);
begin
d := 0;
assign(f,'hanoi.out');
rewrite(f);
writeln('-----------------');
Hn(n,1,2);
writeln(f,'Total: ',d,' step(s)');
close(f);
readln;
end;
BEGIN
runHn(3);
END.
Khi thc hin chng trnh Hanoi.pas vi n = 3 ta thu c kt qu sau:
1. 1 -> 2
2. 1 -> 3
3. 2 -> 3
4. 1 -> 2
5. 3 -> 1
6. 3 -> 2
7. 1 -> 2
Total: 7 step(s)
//
C#
using System;
namespace Tap1
260
{
/*-----------------------------------*
Thap Ha Noi
* -----------------------------------*/
class ThapHaNoi
{
static int d = 0; // em so lan chuyen
static void Main()
{
Console.WriteLine("\n Ha Noi ");
HaNoi(3, 1, 2);
Console.ReadLine();
} // Main
static void HaNoi(int n, int a, int b)
{
if (n == 0) return;
HaNoi(n - 1, a, 6 - a - b);
Console.WriteLine((++d) +
". " + a + " -> " + b);
HaNoi(n - 1, 6 - a - b, b);
}
} // class
} // space
261
2
3
a
b
b
a
Thp H Ni xui
c t a v b k nhau b = (a mod 3)+1
Da vo cc hnh trng buc phi c ta c th m t vic chuyn thp trong trng
hp ny ging nh trong bi ton thp H Ni c, c th l:
Hnh trng
(a: [1..n], b: [ ], c: [ ])
...
(a: [n], b: [ ], c: [1..n 1])
(a: [ ], b: [n], c: [1..n 1])
...
(a: [ ], b: [1..n], c: [ ])
ngha
Lnh
Hnx(n1, a, 6 a
b)
ab
Hnx(n 1, 6 a
b, b)
262
end
b) Trng hp v tr b khng ng st v tr a theo chiu kim ng h:
Cc cp (a, b) khi s l: (1, 3), (2, 1) v (3, 2). c im chung ca cc cp ny
l: nu i t a n b theo chiu kim ng h chng ta phi vt qua c l v tr nm gia
a v b.
Tnh hung
a
b
Thp H Ni xui
c t a v b khng k nhau b (a mod 3) + 1
Cc hnh trng buc phi c khi s l:
Hnh trng
ngha
Lnh
(a: [1..n], c: [ ], b: [ ])
...
(a: [n], c: [ ], b: [1..n 1]
Hnx(n 1, a, b)
a6ab
Hnx(n 1, b, a)
6abb
(a: [ ], c: [ ], b: [1..n])
Hnx(n 1, a, b)
...
(*
Pascal
*)
(*******************************
Ha Noi xuoi
*******************************)
uses crt;
var d: longint;
f: text;
procedure Hnx(n,a,b: byte);
begin
if n = 0 then exit;
if b = (a mod 3)+1 then
begin {b ke a}
Hnx(n-1,a,6-a-b);
inc(d);
writeln(f,d,'. ',a,' -> ',b);
Hnx(n-1,6-a-b,b);
263
end
else {b cach a qua vi tri c}
begin
Hnx(n-1,a,b);
inc(d);
writeln(f,d,'. ',a,' -> ',6-a-b);
Hnx(n-1,b,a);
inc(d);
writeln(f,d,'. ',6-a-b,' -> ',b);
Hnx(n-1,a,b);
end;
end;
procedure runHnx(n: byte);
begin
d := 0;
assign(f,'hnx.out');
rewrite(f);
writeln('-----------------');
Hnx(n,1,2);
writeln(f,'Total: ',d,' step(s)');
close(f);
readln;
end;
BEGIN
runHnx(3);
END.
Li gi runHnx(3) chuyn n tng thp t cc 1 sang cc 2 s cho ta kt qu sau:
1.
2.
3.
4.
5.
6.
7.
8.
1
2
1
3
2
1
2
1
->
->
->
->
->
->
->
->
2
3
2
1
3
2
3
2
9. 3 -> 1
10. 1 -> 2
11. 3 -> 1
12. 2 -> 3
13. 1 -> 2
14. 3 -> 1
15. 1 -> 2
Total: 15 step(s)
// C#
using System;
namespace SangTao1
{
/*-----------------------------------*
Thap Ha Noi Xuoi
* -----------------------------------*/
class ThapHaNoiXuoi
{
static int d = 0;//so buoc chuyen tang thap
static void Main()
{
Console.WriteLine("\n Ha Noi Xuoi");
HaNoiXuoi(3, 1, 2);
Console.WriteLine("\n Total: "
264
+ d + " steps");
Console.ReadLine();
} // Main
static void HaNoiXuoi(int n, int a, int b)
{
if (n == 0) return;
if (b == (a % 3) + 1)
{
HaNoiXuoi(n - 1, a, 6 - a - b);
Console.WriteLine((++d)+". "+a
+" -> "+b);
HaNoiXuoi(n - 1, 6 - a - b, b);
}
else // a c b, c = 6-a-b
{
HaNoiXuoi(n - 1, a, b);
Console.WriteLine((++d)+". "+a+
" -> "+(6-a-b));
HaNoiXuoi(n - 1, b, a);
Console.WriteLine((++d)+". "+
(6-a-b)+" -> "+b);
HaNoiXuoi(n - 1, a, b);
}
}
} // ThapHaNoiXuoi
} // SangTao1
Bi gii
Bi ny tng t nh bi H Ni xui. Ta ch cn xc nh iu kin k gia hai
cc thp v lu n chiu chuyn cc tng thp ngc chiu quay ca kim ng h.
a) Trng hp v tr b ng st v tr a ngc chiu kim ng h:
Theo trng hp ny ta c cc cp (a, b) sau y: (3, 2), (2, 1) v (1, 3).
Hon i v tr ca hai i lng a v b trong iu kin k ca bi ton H Ni xui
ta thu c iu kin k trong trng hp ny l
a = (b mod 3)+1
Tnh hung
1
a
b
Thp H Ni ngc
c t a v b k nhau a = (b mod 3) + 1
265
ngha
Lnh
...
(a: [n], b: [ ], c: [1..n 1])
Hnn(n 1, a, 6
a b)
ab
Hnn(n 1, 6
a b, b)
...
(a: [ ], b: [1..n], c: [ ])
2
3
a
b
b
a
Thp H Ni ngc
c t a v b khng k nhau
a (b mod 3) + 1
Cc hnh trng buc phi c khi s rt ging vi tnh hung tng t ca bi
ton H Ni xui:
266
Hnh trng
ngha
Lnh
(a: [1..n], c: [ ], b: [ ])
...
(a: [n], c: [ ], b: [1..n 1]
Hnn(n 1, a, b)
a6ab
Hnn(n 1, b, a)
6abb
(a: [ ], c: [ ], b: [1..n])
Hnx(n 1, a, b)
...
(*
Pascal
*)
(**************************************
Hano.pas H Ni Ngc
Chuyn php ngc chiu kim ng h.
*************************************)
uses crt;
var d: longint;
f: text;
procedure hnn(n,a,b: byte);
begin
if n = 0 then exit;
if a = (b mod 3)+1 then
begin {b ke a}
hnn(n-1,a,6-a-b);
inc(d);
writeln(f,d,'. ',a,' -> ',b);
hnn(n-1,6-a-b,b);
end
else {b cach a qua vi tri c}
begin
hnn(n-1,a,b);
inc(d);
writeln(f,d,'. ',a,' -> ',6-a-b);
hnn(n-1,b,a);
inc(d);
writeln(f,d,'. ',6-a-b,' -> ',b);
hnn(n-1,a,b);
end;
end;
procedure runhnn(n: byte);
begin
d := 0;
267
assign(f,'hnn.out');
rewrite(f);
writeln('-----------------');
hnn(n,1,2);
writeln(f,'Total: ',d,' step(s)');
close(f);
readln;
end;
BEGIN
runHnn(3);
END.
Kt qu:
1. 1 -> 3
2. 3 -> 2
3. 1 -> 3
4. 2 -> 1
5. 3 -> 2
6. 1 -> 3
7. 3 -> 2
8. 1 -> 3
9. 2 -> 1
10. 1 -> 3
11. 2 -> 1
12. 3 -> 2
13. 2 -> 1
14. 3 -> 2
15. 1 -> 3
16. 3 -> 2
17. 1 -> 3
18. 2 -> 1
19. 3 -> 2
20. 1 -> 3
21. 3 -> 2
Total: 21 step(s)
Nhn xt
Mi xem ta c cm tng rng li gi Hnn(3,1,2) v Hnx(3,1,2) chuyn thp
3 tng t cc 1 sang cc 2 phi cho cng mt s bc chuyn cc tng l 15. Tuy nhin, li gi
Hnn(3,1,2) cho ta 21 bc chuyn cc tng, trong khi li gi Hnx(3,1,2) ch cn 15
bc chuyn cc tng.
Suy ngm mt cht bn s gii thch c nghch l ny.
Hy th gi H Ni ngc chuyn thp 3 tng t cc 3 sang cc 2:
Hnn(3,3,2)
Ta s thy ch cn 15 bc!!!
Li gi H Ni xui chuyn thp 3 tng t cc 1 sang cc 3:
Hnx(3,1,3)
Ta li thy 21 bc.
Nh vy, Hnx v Hnn l i xng lch. Nu hai cc, ngun v ch k nhau th s
ln chuyn thp 3 tng s l 15. Ngc li, khi hai cc khng k nhau th s ln
chuyn thp 3 tng s l 21. Hai cc 1 v 2 l k nhau i vi thp H Ni xui nhng
khng k nhau i vi thp H Ni ngc. Tng t, hai cc 3 v 2 l k nhau i vi
thp H Ni ngc nhng khng k nhau i vi thp H Ni xui.
Ta nhn xt rng: nu ly hai s a, b khc nhau bt k trong ba s 1, 2 v 3 th gia a v
b ch xy ra mt trong hai trng hp loi tr nhau sau y:
b = (a mod 3) +1, hoc a = (b mod 3)+1
Do , quan h k nhau trong hai bi ton Thp H Ni xui v ngc l ph nh
i vi nhau.
268
H Ni xui
H Ni ngc
b = (a mod 3)+1
a v b k nhau
a v b khng k nhau
a = (b mod 3)+1
a v b khng k nhau
a v b k nhau
// C#
using System;
namespace SangTao1
{
/*-----------------------------------*
Thap Ha Noi Nguoc
* -----------------------------------*/
class ThapHaNoiNguoc
{
static int d = 0;
static void Main()
{
Console.WriteLine("\n Ha Noi Nguoc ");
HaNoiNguoc(3, 1, 2);
Console.WriteLine("\n Total: " + d
+ " steps");
Console.ReadLine();
} // Main
static void HaNoiNguoc(int n, int a, int b)
{
if (n == 0) return;
if (a == (b % 3) + 1)
{
HaNoiNguoc(n - 1, a, 6 - a - b);
Console.WriteLine((++d) + ". " +
a + " -> " + b);
HaNoiNguoc(n - 1, 6 - a - b, b);
}
else // b c a, c = 6-a-b
{
HaNoiNguoc(n - 1, a, b);
Console.WriteLine((++d)+". "+a+
" -> "+(6-a-b));
HaNoiNguoc(n - 1, b, a);
Console.WriteLine((++d)+". "+
(6-a-b)+" -> "+b);
HaNoiNguoc(n - 1, a, b);
}
}
} // ThapHaNoiNguoc
} // SangTao1
269
Thp H Ni thng
c t a v b k nhau abs(a b) = 1
Trng hp ny c c t l
abs(a-b) = 1
Hnh trng
(a: [1..n], b: [ ], c: [ ])
ngha
Hnh trng ban u vi v tr b
k v tr a trn ng thng.
abs(a b) = 1
Lnh
270
Hnt(n 1, a, 6 a b);
ab
Hnt(n 1, 6 a b, b);
...
(a: [ ], b: [1..n], c: [ ])
Hnh trng
ngha
...
(a: [n], c: [ ], b: [1..n 1]
(a: [ ], c: [n], b: [1..n 1])
...
(a: [1..n-1], c: [n], b: [ ])
Pascal
Lnh
(a: [1..n], c: [ ], b: [ ])
(*
Tnh hung
Hnt(n 1, a, b)
Hnt(n 1, b, a)
*)
(****************************
HNT.PAS Ha Noi thang
Chuyen n tang thap tu coc a
sang coc b theo duong thang
1->2, 2->1 hoac 2->3, 3->2
1 2 3
****************************)
a2
2b
Hnt(n 1, a, b)
uses crt;
var d: longint;
f: text;
procedure Hnt(n,a,b: byte);
begin
if n = 0 then exit;
if abs(a-b) = 1 then
begin
Hnt(n-1,a,6-a-b);
inc(d);
writeln(f,d,'. ',a,' -> ',b);
Hnt(n-1,6-a-b,b);
end
else
{----------------------------abs(a-b)=2 tuc la a = 1, b = 3
hoac a = 3, b = 1, do do c=2
------------------------------}
begin
Hnt(n-1,a,b);
inc(d);
writeln(f,d,'. ',a,' -> 2');
Hnt(n-1,b,a);
inc(d);
writeln(f,d,'. 2 -> ',b);
Hnt(n-1,a,b);
end;
end;
procedure runHnt(n: byte);
begin
d := 0;
assign(f,'hnt.out');
rewrite(f);
writeln('-----------------');
Hnt(n,1,2);
writeln(f,'Total: ',d,' step(s)');
close(f);
readln;
end;
BEGIN
runHnt(3);
END.
Kt qu
1. 1 -> 2
2. 2 -> 3
3. 1 -> 2
4. 3 -> 2
5. 2 -> 1
6. 2 -> 3
7. 1 -> 2
8. 2 -> 3
9. 1 -> 2
10. 3 -> 2
271
272
11. 2 -> 1
12. 3 -> 2
13. 1 -> 2
Total: 13 step(s)
// C#
using System;
namespace SangTao1
{
/*-----------------------------------*
Thap Ha Noi Thang
* -----------------------------------*/
class ThapHaNoiThang
{
static int d = 0;
static void Main()
{
Console.WriteLine("\n Ha Noi Thang");
HaNoiThang(3, 1, 2);
Console.WriteLine("\n Total: " +
d + " steps");
Console.ReadLine();
} // Main
/*-----------------------------------Ha Noi Thang
* -----------------------------------*/
static void HaNoiThang(int n, int a, int b)
{
if (n == 0) return;
if (Math.Abs(a - b) == 1)
{
HaNoiThang(n - 1, a, 6 - a - b);
Console.WriteLine((++d)+
". "+a+" -> "+b);
HaNoiThang(n - 1, 6 - a - b, b);
}
else // a c b, b c a, c = 6-a-b
{
HaNoiThang(n - 1, a, b);
Console.WriteLine((++d)+
". "+a+" -> "+(6-a-b));
HaNoiThang(n - 1, b, a);
Console.WriteLine((++d)+
". "+(6-a-b)+" -> "+b);
HaNoiThang(n - 1, a, b);
}
}
} // ThapHaNoiThang
} // SangTao1
273
K hiu
x
n
t
h
Mu
xanh
nu
trng
hng
Quy tc
xanh
nu
xanh
hng
trng
H Ni sc mu 5 tng xnxht
v cn chuyn thp t cc 1 sang cc 2 th phi thc hin ti thiu 31 ln chuyn cc
tng nh sau:
1. 1 -> 2
2. 1 -> 3
3. 2 -> 3
4. 1 -> 2
5. 3 -> 1
6. 3 -> 2
7. 1 -> 2
8. 1 -> 3
9. 2 -> 3
10. 2 -> 1
11. 3 -> 1
12. 2 -> 3
13. 1 -> 2
14. 1 -> 3
15. 2 -> 3
16. 1 -> 2
17. 3 -> 1
18. 3 -> 2
19. 1 -> 2
20. 3 -> 1
21. 2 -> 3
22. 2 -> 1
23. 3 -> 1
24. 3 -> 2
25. 1 -> 2
26. 1 -> 3
27. 2 -> 3
28. 1 -> 2
29. 3 -> 1
30. 3 -> 2
31. 1 -> 2
Total: 31 step(s)
Bi gii
iu l th l th tc H Ni sc mu l kh tng qut v ta c th dng n gi
cho cc bi ton v thp H Ni xt. Bng di y cho bit cch s dng th tc
Hnm cho cc trng hp ring.
Mun gi
Hn(n,a,b)
Hnx(n,a,b)
Th gi
Ch thch
s := 'hhh';
Hnm(length(s),a,b);
s cha n k t 'h'
s := 'xxx';
Hnm(length(s),a,b);
s cha n k t 'x'
274
Hnn(n,a,b)
s := 'nnn';
Hnm(length(s),a,b);
s cha n k t 'n'
Hnt(n,a,b)
s := 'ttt';
Hnm(length(s),a,b);
s cha n k t 't'
:=
Thap;
275
Nu s[i] c mu
'x'
Th x l nh th
tc
hnx
'n'
hnn
't'
hnt
'h'
hn
Vy ta ch cn c t tnh cht k
gia Gi
hai cc
v b l xong.
th atc
ngha
Ta thy, da theo lut chuyn, vi thp H Ni c, hai cc a v b khc nhau ty
Hnm(n 1, a, 6 a b)
Chuyn n 1 tng trn cng t a
c xem l k nhau. Vi qua
thpcH
Ni xui, cc b phi ng st cc a theo chiu kim
=6ab
ng h:
ab
b
Hnm(n 1, 6 a b, b)
b = (a mod 3)+1
H Ni sc mu
Chuyn thp trong trng hp a v b k nhau
Vi thp H Ni
ngc, b phi ng st
a theo chiu quay
ngc ca kim ng
h. Ni cch khc, a
276
abs(a-b) = 1
Bng di y m t cc trng hp trn.
Bi ton
K hiu
H Ni C
iu kin a k b
(a b)
Lun ng (True)
H Ni Xui
b = (a mod 3) + 1
H Ni Ngc
a = (b mod 3) + 1
H Ni Thng
abs(a b) = 1
Minh ho
,,,
,
, ,
, ,
, , ,
H Ni sc mu
Cc iu kin k gia hai cc a v b
a, b = 1, 2, 3; a b
Hm Ke (k) khi s c m t nh sau.
function Ke(n,a,b: byte): Boolean;
begin
case s[n] of
'x': ke := (b = (a mod 3)+1);
'n': ke := (a = (b mod 3)+1);
't': Ke := (abs(a-b) = 1);
'h': Ke := True;
end {case};
end;
Tng t, khi hai cc a v b khng k nhau ta cng thc hin cc thao tc nh
nhau.
Bit hm Ke, ta da vo cc thut ton ring cho mi trng hp vit phng n
cho bi ton H Ni sc mu nh sau:
(*---------------------------------------Ha Noi sac mau
x: xanh - xuoi chieu kim dong ho
n: nau - nguoc chieu kim dong ho
t: trang - chuyen thang
h: hong - chuyen tu do
---------------------------------------*)
procedure Hnm(n: byte; a,b: byte);
begin
if n = 0 then exit;
if Ke(n,a,b) then
begin
Hnm(n-1,a,6-a-b);
inc(d);
writeln(f,d,'. ',a,' -> ',b);
Hnm(n-1,6-a-b,b);
end else
begin
Hnm(n-1,a,b);
inc(d);
writeln(f,d,'. ',a,' -> ',6-a-b);
Hnm(n-1,b,a);
inc(d);
writeln(f,d,'. ',6-a-b,' -> ',b);
Hnm(n-1,a,b);
end;
end;
(*
Pascal *)
(**************************************
HNM.PAS Thp H Ni mu
x xanh: Xui chiu kim ng h
n nu: Ngc chiu kim ng h
t Trng: thng theo hng ngang
h H Ni c: kinh in
****************************************)
uses crt;
var d: longint; {dem so buoc chuyen}
f: text; {output file}
s: string; {cau hinh thap}
{---------------------------------------Kiem tra tinh chat ke giua 2 coc a va b
-----------------------------------------}
function Ke(n,a,b: byte): Boolean;
begin
case s[n] of
'x': ke := (b = (a mod 3)+1);
'n': ke := (a = (b mod 3)+1);
't': Ke := (abs(a-b) = 1);
'h': Ke := True;
end {case};
end;
(*---------------------------------------Ha Noi sac mau
x: xanh - xuoi chieu kim dong ho
n: nau - nguoc chieu kim dong ho
t: trang - chuyen thang
h: hong - chuyen tu do
---------------------------------------*)
procedure Hnm(n: byte; a,b: byte); t vit
{------------------------------To chuc goi thu tuc Hnm
------------------------------}
procedure runHnm(Thap:string);
begin
s := Thap;
d := 0;
assign(f,'hnm.out');
rewrite(f);
writeln('-----------------');
277
278
Hnm(length(s),1,2);
writeln(f,'Total: ',d,' step(s)');
close(f);
readln;
end;
BEGIN
runHnm('txhxn');
END.
//
C#
using System;
namespace SangTao1
{
/*-----------------------------------*
Thap Ha Noi
* -----------------------------------*/
class ThapHaNoi
{
static int d = 0;
static char[] s = new char[64];
static void Main()
{
Console.WriteLine("\n Ha Noi Sac Mau");
RunHaNoiSacMau("xnxht", 1, 2);
Console.WriteLine("\n Total: " +
d + " steps");
Console.ReadLine();
} // Main
static bool Ke(char KieuThap, int a, int b)
{
switch (KieuThap)
{
case 'x': return (b == (a % 3) + 1);
case 'n': return (a == (b % 3) + 1);
case 't': return (Math.Abs(a - b) == 1);
}
return true;
}
/*------------------------------------Ha Noi sac mau
x: xanh - xuoi chieu kim dong ho
n: nau - nguoc chieu kim dong ho
t: trang - chuyen thang
h: hong - chuyen tu do
---------------------------------------*/
void HaNoiSacMau(int n, int a, int b)
{
if (n == 0) return;
if (Ke(s[n], a, b))
{
HaNoiSacMau(n - 1, a, 6 - a - b);
279
Console.WriteLine((++d)+
". ("+s[n]+") "+a+" -> "+b);
HaNoiSacMau(n - 1, 6 - a - b, b);
}
else
{
HaNoiSacMau(n - 1, a, b);
Console.WriteLine((++d)+
". ("+s[n]+") "
+a+" -> "+(6-a-b));
HaNoiSacMau(n - 1, b, a);
Console.WriteLine((++d)+
". ("+s[n]+")"
+(6-a-b) +" -> "+b);
HaNoiSacMau(n - 1, a, b);
}
}
static void RunHaNoiSacMau(string w,
int a, int b)
{
d = 0;
w.CopyTo(0, s, 1, w.Length);
HaNoiSacMau(w.Length, a, b);
}
} // ThapHaNoi
} // SangTao1
Hng dn kim th
Ta s dng k thut i snh kim th cc trng hp.
Ta chn v c nh cc gi tr n, a v b. Chng hn, n = 4, a = 1, b = 2.
Khi ta c:
RunHn(n) v RunHnm('hhhh') cho cng kt qu.
RunHnx(n) v RunHnm('xxxx') cho cng kt qu.
RunHnn(n) v RunHnm('nnnn') cho cng kt qu.
RunHnt(n) v RunHnm('tttt') cho cng kt qu.
Nu ghi cc kt qu ny vo cc tp tng ng, sau gi th tc i snh tng
cp hai tp tng ng th c th kim nh c mt s trng hp.
xy dng cc tnh hung kim th khc nhau cn li bn n cc tnh cht
thun nghch ca cc th tc khc nhau. Th d, nh phn tch phn trn, cc li
gi Hnx(3,1,2) v Hnn(3,3,1) pht sinh cng mt s ln chuyn.
Bn hy th pht hin thm s tng ng gia cc li gi Hnm vi cc tham tr
khc nhau.
280
c thm
Lc s
Mt s bi ton v thp H Ni c a vo cc k thi Olympic Tin hc
ti mt s quc gia. Chng ta th tm hiu ci ngun ca cc bi ton thuc
loi ny.
Nm 1883, trn mt t bo Paris c ng bi m t mt tr chi ton hc
ca gio s Claus vi tn l Thp H Ni. Ni dung tr chi c mi ngi
say m lm th chnh l bi ton Thp H Ni c.
Thi th Paris dn chng x nhau mua chi ny v sut
ngy ngi chuyn thp. Trong lch s v cc tr chi thng minh tng c
nhng cn st nh vy. Tnh trung bnh mi th k c mt vi cn st tr chi.
Th k th XX c cn st Rubic, th k XIX l cc tr chi 15 v thp H Ni.
Bi ton ny ni ting n mc tr thnh kinh in trong cc gio trnh v thut
gii quy v c trnh by trong cc thng bo chnh thc ca cc phin
bn chun ca cc ng trnh nh ALGOL-60, ALGOL-68, Pascal, Delphy, C,
C++, Ada,... khi mun nhn mnh v kh nng quy ca cc ngn ng .
Theo nh nghin cu Henri De Parville cng b vo nm 1884 th tc gi
ca tr chi thp H Ni c tn tht l nh ton hc Eduard Lucas, ngi c
nhiu ng gp trong lnh vc s lun. Mi khi vit v ti gii tr th ng i
tn l Claus. Bn c rng Claus l mt hon v cc ch ci ca t Lucas.
De Parville cn k rng bi ton thp H Ni bt ngun t mt tch truyn
k n . Mt nhm cao tng n gio c giao trng trch chuyn dn
64 a vng gia ba cc kim cng theo cc iu kin ni bi ton Thp
H Ni c. Khi no hon tt cng vic, tc l khi chuyn xong to thp vng 64
tng t v tr ban u sang v tr kt thc th cng l thi im tn th. S vic
ny c xy ra hay khng ta s xt bi tp 8.10.
Li gii c cng b u tin cho bi ton thp H Ni l ca Allardice v
Frase, nm 1884.
Nm 1994 David G. Poole i hc Trent, Canada vit mt bi kho
cu cho t Mathematics Magazine s thng 12 nhan "V cc thp v cc
tam gic ca gio s Claus" cng vi mt ph "Pascal bit H Ni". Poole
lit k 65 cng trnh kho cu bi ton thp H Ni ng trn cc tp ch
ton-tin trong khong mi nm. Tc gi cng ch ra s lin quan gia cc
cng thc tnh s ln chuyn cc tng thp v mt phng php quen bit
n
dng tnh cc h s ca dng khai trin nh thc Newton (a + b) . Phng
php ny c gi l Tam gic Pascal, mang tn nh ton hc kim vt l hc
Php Blaise Pascal (1623-1662), ngi ch to chic my tnh quay tay u
tin trn th gii.
Mt s nh nghin cu trong v ngoi nc c bn lun v a danh
H Ni. Theo ti vn ny vn cn ng. Hu ht cc bi vit xoay quanh
ti chuyn thp ni trn u dng thut ng bi ton thp H Ni. Khi gii thiu
v bi ton H Ni nhiu thp Dudeney t tn l bi ton ca Reve (The
Reve's Puzzle). Tuy nhin, nhiu nh nghin cu cho rng tt hn c l nn
t tn v phn loi theo tn nguyn thu ca bi ton, ngha l Thp H Ni.
Ngoi cc dng Thp H Ni lit k phn trn mt s tc gi cn
xut nhng dng kh k l, chng hn nh bi ton sau y.
281
H Ni nhiu thp
Trong tr chi ny ngi ta lm thm nhng cc, chng hn thay v ba ta dng bn
cc v cng c th b tr thp ti nhiu cc. kin ny do H.E. Dudeney, mt tc gi
hng u v ton hc gii tr ngi Anh a ra vo nm 1908. c nhiu bi ng li
gii cho bi ton ny, c nhng bi mi xut hin gn y vo nhng nm 1988 v
1989. D vy cha ai chng minh c r rng s ln chuyn ca bi gii l ti thiu
nh lm vi cc dng thp H Ni khc.
Bi tp
Bn hy th lp cng thc tnh s ln chuyn cc tng ti thiu cho cc bi ton
sau:
Thp H Ni,
Thp H Ni Xui,
Thp H Ni Ngc v
Thp H Ni Thng.
Li cm n Cc t liu trn v mt s t liu khc trong bi c trch dn t cc
bi vit ca gio s vin s Nguyn Xun Vinh, Khoa K thut khng gian, i hc
Michigan, cng tc vin NASA, Hoa K. Tc gi xin chn thnh cm n gio s cho
php trch dn v ch gio v cc phng php truyn th tri thc khoa hc cho gii tr.
NXH
8/4/2008
Sa ngy 4/4/09
282
Li gii thiu
Sch trnh by c h thng cc ph-ng php thit
k thut ton minh ha qua cc bi ton thi hc
sinh gii v Olimpic hc sinh v sinh vin trong
n-c, khu vc v quc t. Cc bi ton u -c
phn tch y km theo thut ton v ton vn
ch-ng trnh vit trn ngn ng C# v Pascal.
Sch l ti liu b ch cho hc sinh trung hc,
gio vin cc tr-ng ph thng v cao ng v
sinh vin cc tr-ng i hc mun hon thin kin
thc tham d cc k thi Olimpic Tin hc quc
gia v quc t.
Cc ch-ng trnh song ng Pascal v C# gip cho
bn c chuyn i nhanh chng sang cc mi
tr-ng lp trnh tin tin.