Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 35 trang
THÔNG TIN TÀI LIỆU
Cấu trúc
MỤC LỤC
Khái niệm
Các thao tác thường dùng đối với Heap Max
Khai báo
UpHeap
DownHeap
Push
Pop
Dijkstra Heap
Một số bài tập ứng dụng
1. Bài tập 1: Heapuri
2. Bài tập 2: Thả xốp
3. Bài tập 3:PILOT
Bài tập4:Tiểu thuyết trinh thám
Bài tập 5: Cezar
Bài tập 6:Toy Cars
Bài tập 7:BASE3
Yêu cầu:
INPUT: BASE3.INP
OUTPUT: BASE3.OUT
Giới hạn
Ví dụ:
Một số bài tập vận dụng
Bài tập 1: BOCSOI13
Bài tập 2: Kế hoạch làm bài
Bài tập 3: CATUN
Bài tập 3: Barbar
Bài tập 4:Cầu cảng
4. Bài tập 5:K TỔNG BÉ NHẤT
Bài tập 6: BINLADEN
Tài liệu tham khảo
Nội dung
MỤC LỤC
MỤC LỤC...............................................................................................................................1
Khái niệm................................................................................................................................2
Các thao tác thường dùng đối với Heap Max.........................................................................2
Khai báo..............................................................................................................................2
UpHeap................................................................................................................................2
DownHeap...........................................................................................................................3
Push.....................................................................................................................................4
Pop.......................................................................................................................................4
Dijkstra Heap.......................................................................................................................5
Một số bài tập ứng dụng.........................................................................................................6
1.Bài tập 1: Heapuri............................................................................................................6
2.Bài tập 2: Thả xốp............................................................................................................8
3.Bài tập 3:PILOT.............................................................................................................10
Bài tập4:Tiểu thuyết trinh thám........................................................................................13
Bài tập 5: Cezar ................................................................................................................18
Bài tập 6:Toy Cars............................................................................................................22
Bài tập 7:BASE3 ..............................................................................................................26
Một số bài tập vận dụng........................................................................................................30
Bài tập 1: BOCSOI13.......................................................................................................30
Bài tập 2: Kế hoạch làm bài..............................................................................................31
Bài tập 3: CATUN............................................................................................................31
Bài tập 3: Barbar...............................................................................................................32
Bài tập 4:Cầu cảng............................................................................................................33
4.Bài tập 5:K TỔNG BÉ NHẤT.......................................................................................33
Bài tập 6: BINLADEN......................................................................................................34
Tài liệu tham khảo.................................................................................................................35
1
CHUYÊN ĐỀ: CẤU TRÚC DỮ LIỆU HEAP
Khái niệm
Heap là một trong những cấu trúc dữ liệu đặc biệt quan trọng, nó giúp ta có thể giải
được nhiều bài toán trong thời gian cho phép. Độ phức tạp thông thường khi làm việc với
Heap là O(logN).
Heap thực chất là một cây cân bằng thỏa mãn các điều kiện sau:
• Một nút có không quá 2 nút con.
• Với Heap Max thì nút gốc là nút lớn nhất, mọi nút con đều không lớn hơn nút cha
của nó. Với Heap Min thì ngược lại.
Mặc dù được mô tả như cây nhưng Heap có thể được biểu diễn bằng mảng. Nút con
của nút i là 2*i và 2*i+1. Do Heap là cây cân bằng nên độ cao của 1 nút luôn nHeap then exit; // Nếu i không có nút con thì không làm việc
if (j < nHeap) and (Heap[j] < Heap[j+1]) then Inc(j); // Nếu i có 2 nút con thì
chọn nút ưu tiên hơn
if Heap[i] < Heap[j] then // Nếu nút cha nhỏ hơn nút con
begin
swap(Heap[i] , Heap[j]); // Đổi chỗ 2 phần tử trong Heap
DownHeap(j); // Tiếp tục di chuyển xuống dưới
end;
end;
Push
Đưa 1 phần tử mới vào Heap: Thêm 1 nút vào cuối Heap và tiến hành UpHeap từ
đây:
Procedure Push(x : LongInt);
Begin
Inc(nHeap); // Tăng số phần tử của Heap
Heap[nHeap] := x; // Thêm x vào Heap
UpHeap(nHeap);
End;
Pop
Rút ra 1 phần tử ở vị trí v trong Heap: Gán Heap[v] := Heap[nHeap] rồi tiến hành
chỉnh lại Heap:
Function Pop(v : LongInt) : LongInt;
Begin
Pop := Heap[v]; // Lấy phần tử ở vị trí v ra khỏi Heap
Heap[v] := Heap[nHeap]; // Đưa phần tử ở cuối Heap vào vị trí v
Dec(nHeap); // Giảm số phần tử của Heap đi 1
4
{Chỉnh lại Heap}
UpHeap(v);
DownHeap(v);
End;
Ngoài ra, khi sử dụng thuật toán Dijkstra/Prim kết hợp cấu trúc Heap, bạn còn
có thể sử dụng cách Push và Pop khác thuận lợi hơn so với cách trình bày ở trên:
Dijkstra Heap
1/ Update – Dijkstra:
Procedure Update(v : LongInt); // Đỉnh v vừa được sửa nhãn, cần chỉnh lại Heap
var
child , parent : LongInt;
begin
child := pos[v]; // child là vị trí của đỉnh v trong Heap
if child = 0 then // Nếu đỉnh v chưa có trong Heap
begin
Inc(nHeap); // Tăng số phần tử của Heap
child := nHeap; // Đưa v vào cuối Heap
end;
parent := child div 2; // parent là nút cha của child
while (parent > 0) and (d[Heap[parent]] > d[v]) do // Nếu đỉnh ở nút parent
kém ưu tiên hơn v thì bị “kéo xuống” nút child
begin
Heap[child] := Heap[parent]; // Đẩy đỉnh được lưu trong nút cha xuống nút con
pos[Heap[child]] := child; // Ghi nhận lại vị trí mới của đỉnh đó
child := parent; // Tiếp tục di chuyển lên
parent := child div 2;
end;
Heap[child] := v; // Thao tác “kéo xuống” ở trên sẽ tạo ra 1 ô trống ở nút child để đặt v vào
pos[v] := child; // Ghi nhận vị trí mới của đỉnh v trong Heap
end;
2/ Pop – Dijkstra:
Function Pop : LongInt; // Lấy từ Heap đỉnh có nhãn tự do nhỏ nhất
var
r , v , c : LongInt;
begin
Pop := Heap[1]; // Nút gốc là nút có nhãn tự do nhỏ nhất
v := Heap[nHeap]; // v là đỉnh ở nút lá cuối Heap, sẽ được đảo lên đầu và vun đống
Dec(nHeap); // Giảm số phần tử của Heap
r := 1; // Bắt đầu từ nút gốc
while r*2 = d[v] then break; // Nếu v ưu tiên hơn thì không làm việc nữa
Heap[r] := Heap[c]; // Chuyển đỉnh lưu ở nút con lên nút cha
pos[Heap[r]] := r; // Cập nhật lại vị trí mới trong Heap của đỉnh đó
r := c; // Tiếp tục di chuyển xuống dưới
5
end;
Heap[r] := v; // Đỉnh v được đặt vào vị trí r để đảm bảo cấu trúc Heap
pos[v] := r; // Ghi nhận vị trí mới của đỉnh v trong Heap
end;
Một số bài tập ứng dụng
1. Bài tập 1: Heapuri
Cho danh sách gồm N phần tử. Chúng ta thực hiện một số thao tác trên danh sách. Có 3
loại thao tác sau :
- Thao tác 1 : Cho phần tử x vào danh sách
- Thao tác 2 : Xóa phần tử thứ t (theo thứ tự nhập vào)
- Thao tác 3: Lấy ra phần tử nhỏ nhất trong danh sách
Yêu cầu: Hãy cho biết các kết quả của thao tác 3 ?
INPUT: HEAPURI.INP
-
Dòng 1: N
-
Các dòng tiếp theo là dãy thao tác cần xử lý theo định dạng 1 x, 2 x hoặc 3 tương
ứng là thao tác 1, 2 và 3
OUTPUT : HEAPURI.OUT
- Ghi trên nhiều dòng, mỗi dòng là kết quả của thao tác 3 theo thứ tự trong file input.
Ví dụ :
HEAPURI.INP
HEAPURI.OUT
9
1
1
1
3
1
2
3
2
3
4
7
9
4
2
7
2
1
4
Dễ thấy đây là một danh sách động (số lượng phần tử thay đổi), vì vậy ta xây dựng một
heapmin để lấy ra giá trị nhỏ nhất ở các thao tác 3. Để xóa phần tử thứ t theo thứ tự nhập
vào thì ta lưu thêm một mảng Pos.
#include
#include
#define maxn 200010
int N, L, NR;
int A[maxn], Heap[maxn], Pos[maxn];
6
void push(int x)
{
int aux;
while (x/2 && A[Heap[x]] i then sort(i,y);
end;
{*------------------------------------------------------------*}
{*------------------------------------------------------------*}
procedureinkq;
begin
assign(fo,tfo);rewrite(fo);
write(fo,res);
close(fo);
end;
{*------------------------------------------------------------*}
{*------------------------------------------------------------*}
{*------------------------------------------------------------*}
{*------------------------------------------------------------*}
BEGIN
randomize;
nhap;
17
sort(1,n);
xuli;
inkq;
END.
Bài tập 5: Cezar
Tại HT Land, có tất cả n thượng nghị sĩ ở trong n ngôi biệt thự (đánh số từ 1 đến n),
giữa 2 ngôi nhà có một đường đi duy nhất: đường đi trực tiếp hoặc không trực tiếp (đi qua
các con đường khác). Tất cả các ngôi nhà đều đi được đến nhau.
Mỗi thượng nghị sĩ khi đi từ nhà mình đến thượng viện, phải trả 1 USD khi đi qua
một con phố (phố = đường nối trực tiếp 2 nhà bất kỳ). HT – người đứng đầu thượng viện đã nghĩ cách làm sao cho số tiền mà các thượng nghĩ sĩ phải trả là tối thiểu. Vì vậy, HT
quyết định
• Có k con phố miễn phí (thượng nghị sĩ sẽ không phải trả tiền khi đi trên con
phố này)
• Đặt tòa nhà thượng viện ở một trong n ngôi nhà
Bạn hãy viết chương trình tính xem chi phí tối thiểu là bao nhiêu?
INPUT: CEZAR.INP
- Dòng 1: Số nguyên n và k tương ứng là số ngôi nhà ở HT land và số đường phố
miễn phí
- N – 1 dòng tiếp theo, mỗi dòng chứa 2 số i j có nghĩa là có con phố nối ngôi nhà i
và ngôi nhà j
OUTPUT: CEZAR.OUT
Chi phí tối thiểu phải trả
Giới hạn:
•
Ví dụ
CEZAR.INP
13 3
12
23
28
78
75
54
56
89
8 10
10 11
10 12
10 13
CEZAR.OUT
11
Giải thích
Có nhiều phương án
giải quyết: Đây là 1
phương án:
– 5-7, 7-8, 8-10
là
những
đường
miễn
phí
– 8 là thượng
viện
Chi phí tối thiểu là:
11.
18
6
3
1
4
2
5
7
8
10
9
11
12
13
Time limit:0.5 s/test
Thuật toán:
1. Chúng ta sẽ tìm
con đường phải trả phí đi lại.
2. Khởi tạo D[i] = trọng số của đỉnh i với ý nghĩa = số lượng người đi đến thượng
viện phải đi qua con đường này. Ban đầu
3. Tại mỗi bước chúng ta sẽ cho các nút lá vào Heap, mỗi lần lấy 1 phần tử trong heap
chúng ta sẽ update lại trọng số của đỉnh kề với đỉnh vừa lấy ra và nếu đỉnh vừa
update thành nút lá ta lại cho vào trong heap. Sau khi lấy xong
nhật đáp án.
Const
tfi='cezar.inp';
tfo='cezar.out';
oo = 1000000000;
Type
arr1=array[0..100000] of longint;
arr2=array[0..100000] of boolean;
arr3=array[0..15000] of longint;
arr4=array[0..15000] of arr3;
Var
fi,fo
: text;
heap,head,ke,d,c,pos,cost,trace,deg : arr1;
free
: arr2;
k,n,nheap,f,r,sum,res
: longint;
count : arr4;
{===============================}
Procedure nhap;
Var
i,u,v :
longint;
Begin
Assign(fi,tfi);Reset(fi);
read(fi,n,k);
For i := 1 to n-1 do
Begin
read(fi,u,v);
d[i] := u;
c[i] := v;
inc(deg[u]);
inc(deg[v]);
ENd;
head[1] := deg[1];
For i := 2 to n+1 do
Begin
head[i] := head[i-1] + deg[i];
19
đỉnh thì cập
End;
For i := 1 to n-1 do
Begin
u := d[i];
v := c[i];
ke[head[u]] := v;
ke[head[v]] := u;
cost[head[u]] := 1;
cost[head[v]] := 1;
dec(head[u]);
dec(head[v]);
End;
Close(fi);
End;
{===============================}
Procedure khoitao;
Var
i :longint;
Begin
Fillchar(free,sizeof(free),true);
For i := 1 to n do
BEgin
pos[i] := 0;
cost[i] := 1;
End;
nheap := 0;
End;
{===============================}
Procedure downheap(root : longint);
Var
child,u : longint;
BEgin
u := heap[root];
repeat
child := root*2;
If (child cost[heap[child+1]])
then inc(child);
If (child >nheap) or (cost[heap[child]]>= cost[u]) then break;
heap[root] := heap[child];
pos[heap[root]] := root;
root := child;
Until false;
heap[root] := u;
pos[u] := root;
End;
{===============================}
Procedure upheap(child : longint);
Var
root,u : longint;
Begin
u := heap[child];
20
Repeat
root := child div 2;
If (root=0) or (cost[heap[root]] 0 do
begin
pop;
if (xi = 0) then
begin
write(fo,d[xi,yi]);
exit;
end;
update;
end;
write(fo,0) ;
end ;
begin
assign(fi,tfi);reset(fi);
assign(fo,tfo);rewrite(fo);
Nhap;
init;
xuly;
close(fi);
close(fo) ;
end.
Một số bài tập vận dụng
Bài tập 1: BOCSOI13
Bước vào tiểu học, Bé Bi được cô giáo chủ nhiệm cho làm lớp trưởng. Nhân dịp kỷ
niệm ngày thành lập trường, Bé Bi tổ chức cho cả lớp chơi 1 trò chơi sau:
Có N đống sỏi xếp thành một hàng, đống thứ i có A i viên sỏi. Ta có thể ghép hai đống
sỏi bất kỳ thành một đống và mất một chi phí bằng 5% tổng hai đống sỏi đó. Hãy tìm cách
ghép N đống sỏi này thành một đống với chi phí là nhỏ nhất.
Ví dụ: Nếu chúng ta có 4 đống sỏi với số lượng sỏi là 10, 11, 12 và 13.
- Bước 1: Ghép 2 đống 10 và 11 thành 1 đống có số lượng 21 (chi phí là 1.05)
- Bước 2: Ghép đống 21 vừa thu được với đống 12 thành đống có số lượng 33 (chi
phí 1.65)
- Bước 3: Ghép đống 33 vừa thu được với đống 13 thành 1 đống cuối cùng có số
lượng sỏi là 46 (chi phí 2.3)
- Vậy tổng chi phí là 5.00. Tuy nhiên đây không phải là phương án ghép đống tối ưu,
chúng ta có phương án ghép 4 đống này thành 1 đống với chi phí nhỏ nhất là 4.60.
Các bạn hãy tìm giúp Bé Bi phương án chơi tối ưu nhé!
INPUT:BOCSOI13.INP:
-
Dòng 1: Số nguyên dương N
là số đống sỏi.
-
Dòng tiếp theo, ghi N số nguyên dương, tương ứng là số lượng sỏi trong từng đống.
Số lượng sỏi không vượt quá 10.000.
OUTPUT:BOCSOI13.OUT:
- Ghi 1 số thực duy nhất là chi phí nhỏ nhất phải trả để ghép N đống sỏi thành 1
đống. Kết quả ghi dưới dạng 2 chữ số sau dấu thập phân.
30
Ví dụ:
BOCSOI13.INP
4
10 11 12 13
2
11
BOCSOI13.OUT
4.60
0.10
Bài tập 2: Kế hoạch làm bài
Nobita được giao n bài tập về nhà đánh số từ 1 tới n. Mỗi bài tập cần đúng 1 đơn vị
thời gian để làm và tại mỗi thời điểm, Nobita chỉ có thể làm được 1 bài tập. Bài tập thứ I
cần hoàn thành không muộn hơn thời điểm t i và nếu bài thứ I bị nộp muộn thì Nobita sẽ bị
thày giáo cho pi điểm 0.
Giả sử Nobita định làm bài tập từ thời điểm a đến hết thời điểm b. Hãy giúp Nobita lên
kế hoạch làm bài tập để số điểm 0 phải nhận là ít nhất.
INPUT: PENALTY.INP
-
Dòng 1: Chứa 3 số nguyên dương n
;
-
N dòng tiếp theo, dòng thứ I chứa hai số nguyên dương ti, pi
OUTPUT: PENALTY.OUT
Một số duy nhất là số điểm 0 tối thiểu phải nhận
Ví dụ:
PENALTY.INP PENALTY.OUT Giải thích
5 1 4
25
Làm bài 1 từ thời điểm 1 đến thời điểm 2.
2 100
Làm bài 4 từ thời điểm 2 đến thời điểm 3.
2 20
4 5
Làm bài 5 từ thời điểm 3 đến thời điểm 4.
4 10
Bài 2 và bài 3 bị nộp muộn
4 6
Bài tập 3: CATUN
Tại vương quốc HT có N thị trấn đánh số từ 1 đến N và M con đường nối 2 thị trấn bất
kỳ. Trong số N thị trấn thì có K thị trấn là pháo đài chống giặc ngoại xâm. Khi có giặc
ngoại xâm, 1 pháo đài bất kỳ sẽ bảo vệ những thị trấn gần nó nhất. Nếu co 1 thị trấn nào
đó có khoảng cách tới 2 pháo đài bằng nhau thì thị trấn này được bảo vệ bởi pháo đài có
chỉ số nhỏ hơn?
INPUT: CATUN.IN
-
Dòng 1: N, M và K (
-
Dòng 2: K số nguyên dương là chỉ số của K pháo đài
M dòng tiếp theo, mỗi dòng ghi 3 số x, y, z có nghĩa là có con đường 2 chiều nối
thị trấn x với thị trấn y có chiều dài là z.
OUTPUT: CATUN.OUT
31
-
Ghi N số nguyên dương, số thí I là chỉ số của pháo đài bảo vệ thị trấn i. Nếu thị trấn
I không được bảo vệ bởi pháo đài nào thì ghi số 0
Ví dụ:
CATUN.IN
8 9 2
2 5
1 3 6
1 5 3
1 6 1
2 3 9
5 6 5
6 8 7
3 6 2
4 7 1000
2 8 5
Time limit: 0.2s
CATUN.OUT
5 0 5 0 0 5 0 2
Bài tập 3: Barbar
Sau cuộc chiến tranh thần thánh, HT bị bắt giam vào ngục tối là một bảng cỡ R*C (R dòng
và C cột). Tại một ô có thể di chuyển sang 4 ô kề cạnh. Trong ngục có 1 số ô là có thể di
chuyển tự do, một số ô là tường không thể di chuyển qua và đặc biệt một số ô bị chiếm
giữ bởi các con rồng lửa (không thể đi lại gần nếu không muốn bị cháy thành than). Bạn
hãy giúp HT di chuyển qua ngục tối sao cho khoảng cách ngắn nhất đến các con rồng lửa
là lớn nhất?
INPUT: BARBAR.IN
-
Dòng 1: R và C (
-
R dòng tiếp theo, mỗi dòng ghi C ký tự biểu diễn ngục tối.
“.” Ô di chuyển tự do
“*” Tường
“D” Rồng lửa
“I”: Vị trí xuất phát của HT
“O”: Vị trí thoát khỏi ngục tối
OUTPUT: BARBAR.OUT
- Một số duy nhất là giá trị lớn nhất của khoảng cách ngắn nhất đến các con rồng lửa
khi HT di chuyển ra khỏi ngục tối. Nếu không có cách di chuyển ghi -1
Ví dụ:
Giải thích
BARBAR.IN
BARBAR.OUT
..........
10 10
2
.Iooo.D...
....o.....
..D.o.D...
.*..oo....
D*...ooooo
*...D....o
..........
.I....D...
..........
..D...D...
.*........
D*........
32
*...D.....
..****....
...O......
..........
..****...o
...Ooooooo
..........
Time limit: 0.4s
Bài tập 4:Cầu cảng
Một cầu cảng có m cầu cảng để tiếp nhận các tàu cập bến. Tại một thời điểm, mỗi cầu
cảng chỉ có thể tiếp nhận không quá 1 tàu. Ban đầu các cầu cảng đều trống và có n tàu xin
đăng ký cập bến, tàu thứ i muốn đậu ở cảng ngày sau thời điểm
tới hết thời điểm . Có
thể coi thời gian tàu thứ i muốn đậu ở cảng là một khoảng
trên trục thời gian. Tàu
đã vào cầu cảng nào thì sẽ đậu ở đó trong suốt thời gian nằm cảng.
Yêu cầu : Hãy cho biết với m cầu cảng đã cho, có thể tiếp nhận được tối đa bao nhiều tàu
và chỉ ra lịch trình tiếp nhận tại mỗi cầu cảng ?
INPUT:SEAPORTS.INP
-
Dòng 1: Chứa 2 số nguyên dương
-
N dòng tiếp theo, dòng thứ i chứ 2 số nguyên
OUTPUT:SEAPORTS.OUT
- Dòng 1 : Ghi số lượng tàu được tiếp nhận phục vụ
- Dòng 2 : Ghi n số nguyên, số thứ i là số hiệu cầu cảng sẽ tiếp nhận tàu thứ i trong
trường hợp tàu thứ i được tiếp nhận, còn nếu tàu thứ i không được tiếp nhận thì số
thứ i là 0.
Ví dụ :
SEAPORTS.INP
SEAPORTS.OUT
25
4
03
11220
35
02
25
14
4. Bài tập 5:K TỔNG BÉ NHẤT
Cho 2 dãy số nguyên A và B. Với mọi số A[i] thuộc A và B[j] thuộc B (1 ≤ A i, Bi ≤ 109 )
người ta tính tổng nó. Tất cả các tổng này sau khi được sắp xếp không giảm sẽ tạo thành
dãy C. Nhiệm vụ của bạn là: Cho 2 dãy A, B. Tìm K số đầu tiên trong dãy C
INPUT: KMIN.INP
- Dòng đầu tiên gồm 3 số: M, N, K (1≤M, N, K ≤ 50.000)
- M dòng tiếp theo gồm M số mô tả dãy A
- N dòng tiếp theo gồm N số mô tả dãy B
OUTPUT:KMIN.OUT
33
- Gồm K dòng tương ứng là K phần tử đầu tiên trong dãy C.
Ví dụ:
KMIN.INP
KMIN.OUT
446
3
1
4
2
4
3
5
4
5
2
5
3
4
5
Time limit: 1s
Bài tập 6: BINLADEN
Trùm khủng bố Bin Laden trốn trong 1 căn hầm được đào sâu xuống mặt đất M tầng,
mỗi tầng có N phòng. Các phòng được ngăn cách bằng các cửa rất khó phá. Các phòng có
cửa xuống phòng ngay phía dưới và 2 phòng ở 2 bên. Từ trên mặt đất có N cửa xuống N
phòng tầng -1. Bin Laden ở tầng dưới cùng (tầng -M) phòng thứ N (phòng ở bên phải
nhất). Mỗi cửa được làm bằng một kim loại khác nhau với độ dày khác nhau nên việc phá
cửa cần thời gian khác nhau.
Bạn hãy tìm cách đi từ mặt đất xuống phòng của Bin Laden nhanh nhất không hắn thoát
mất.
INPUT: BINLADEN.INP
-
Dòng 1 ghi M và N
-
Dòng 2 đến 2M + 1, dòng chẵn ghi N số, dòng lẻ ghi N - 1 số là chi phí để phá cửa.
Chi phí của các cánh cửa thuộc [0, 1000].
OUTPUT: BINLADEN.OUT
- Ghi ra 1 số là thời gian nhỏ nhất để đến được phòng của Bin Laden
Ví dụ:
BINLADEN.INP
42
99 10
1
10 99
1
99 10
1
10 99
1
BINLADEN.OUT
44
+--99--+--10--+
|
|
|
|
1
|
|
|
|
+--10--+--99--+
|
|
|
|
1
|
|
|
|
+--99--+--10--+
|
|
|
|
1
|
|
|
|
+--10--+--99--+
|
|
|
|
1
|
34
|
|
|
+------+------+
Đi theo đường zigzac
Tài liệu tham khảo
1. Nguồn bài tập: Thày Nguyễn Thanh Tùng, Thày Lê Minh Hoàng, Rumania OI,
Poland OI, Russian OI, vn.spoj.pl.
2. Giải thuật và lập trình – T.S Lê Minh Hoàng – ĐHSP Hà Nội
3. Website: www.infoarena.ro
4. Test và solution các Thày cô có thể liên hệ với tác giả để download.
35
[...]... := 1; End; nheap := 0; End; {===============================} Procedure downheap(root : longint); Var child,u : longint; BEgin u := heap[ root]; repeat child := root*2; If (child cost [heap[ child+1]]) then inc(child); If (child >nheap) or (cost [heap[ child]]>= cost[u]) then break; heap[ root] := heap[ child]; pos [heap[ root]] := root; root := child; Until false; heap[ root]... Procedure upheap(child : longint); Var root,u : longint; Begin u := heap[ child]; 20 Repeat root := child div 2; If (root=0) or (cost [heap[ root]] h[i] then begin doicho(h[i div 2],h[i]); upheap(i div 2); end; end; {* *} proceduredownheap(i : longint); var j : longint; 15 begin j := 2 * i; if j >nh then exit; if (j h[j+1]) then inc(j); if h[i] > h[j] then begin doicho(h[i],h[j]); downheap(j); end; end;... tồi lớn nhất và đặt lên giá, sau đó lấy món P[i] để lên sàn 3 Dễ dàng nhận thấy có thể sử dụng cấu trúc Heap để thực hiện thuật giải trong thời gian N.logK const tfi tfo type = = 'toycars.inp'; 'toycars.out'; arr1 arr2 = = array[0 1000000] of longint; array[0 100000] of boolean; var 23 fi,fo:text; n,k,p,res,nheap,x,dem,vc:longint; c,deg,d,a,pos,b,vt,next:arr1; free:arr2; { ... -*} procedureupheap(i : longint); begin if (i = 1) or (h[i] < h[i div 2]) then exit; if h[i div 2] < h[i] then begin doicho(h[i div 2],h[i]); upheap(i div 2); end; end; {* -*} proceduredownheap(i : longint); var j : longint; begin j := 2 *i; if j >nh then exit; if (j ...CHUYÊN ĐỀ: CẤU TRÚC DỮ LIỆU HEAP Khái niệm Heap cấu trúc liệu đặc biệt quan trọng, giúp ta giải nhiều toán thời gian cho phép Độ phức tạp thông thường làm việc với Heap O(logN) Heap thực... LongInt); Begin Inc(nHeap); // Tăng số phần tử Heap Heap[nHeap] := x; // Thêm x vào Heap UpHeap(nHeap); End; Pop Rút phần tử vị trí v Heap: Gán Heap[ v] := Heap[ nHeap] tiến hành chỉnh lại Heap: Function... Begin Pop := Heap[ v]; // Lấy phần tử vị trí v khỏi Heap Heap[v] := Heap[ nHeap]; // Đưa phần tử cuối Heap vào vị trí v Dec(nHeap); // Giảm số phần tử Heap {Chỉnh lại Heap} UpHeap(v); DownHeap(v);