Professional Documents
Culture Documents
Phân tích
+ Sắp xếp tăng từng dãy số
+ Dùng 2 biến chạy xuôi và ngược là i và j. Biến i dùng duyệt xuôi mảng b(N) bắt đầu từ vị
trí 1, biến j dùng duyệt ngược mảng c(N) bắt đầu từ vị trí N.
+ Vòng lặp thực hiện trong khi (i<=N) và (j>=1):
- Tính v=bi+cj
- Nếu v>=0 thì giảm j (để |v| giảm đi)
Ngược lại nếu v<0 thì tăng i (vì số âm khi được tăng lên thì trị tuyệt đối của nó
giảm đi.
Văn bản hương trình.
const fi = 'seqgame.in';
fo = 'seqgame.out';
max = 100000;
type tarray = array[1..max] of Integer;
var b, c : tarray;
n, min : integer;
procedure read_input;
var f : text;
i, temp : Integer;
begin
assign(f, fi); reset(f);
readln(f, n);
for i := 1 to n do read(f, b[i]);
readln(f);
for i := 1 to n do begin
read(f, c[i]);
end;
close(f);
end;
procedure quicksort(var k: TArray; l, r: Integer);
var i, j: integer;
temp, key: Integer;
begin
if l >= r then exit;
key := k[(l + r) div 2];
i := l; j := r;
repeat
while k[i] < key do inc(i);
while k[j] > key do dec(j);
if i <= j then begin
if i < j then begin
temp := k[i]; k[i] := k[j]; k[j] := temp;
end;
inc(i); dec(j);
end;
until i > j;
QuickSort(k, l, j);
QuickSort(k, i, r);
end;
procedure solve;
var v, i, j: integer;
begin
min := maxInt;
i:=1; j:= n;
while (i<=n) and (j>1) do begin
v := b[i]+c[j];
if v>=0 then dec(j)
else if v<0 then inc(i);
if abs(b[i]+c[j])<min then min:=abs(b[i]+c[j]);
end;
end;
procedure write_out;
var f: text;
begin
assign(f, fo); rewrite(f);
write(f, min);
close(f);
end;
BEGIN
read_input;
quicksort(b, 1, n);
quicksort(c, 1, n);
solve;
write_out;
END.
Bài 3. SỐ 0 CUỐI CÙNG
Cho một dãy số khoảng 1000000 kí tự số toàn 0 và 1. Biết rằng các số 0 đứng trước các chữ số 1:
000....0011...11. Hãy cho biết vị trí của số 0 cuối cùng trong dãy.
Thuật toán:
Ta tiến hành tìm kiếm nhị phân trên xâu kí tự để tìm ra vị trí số 0 cuối cùng như sau:
- Tìm phần tử giữa xâu đang xét
- So sánh kí tự ở vị trí giữa xâu với kí tự 0.
- Nếu kí tự giữa xâu là kí tự 0 thì ta tìm ở nửa sau của xâu, nếu không phải kí tự 0 (mà là 1)
thì ta tìm ở nửa trước của xâu.
1.d:=1; c:=length(s);
2. trong khi d<c thì
2.1 g:=(d+c+1) div 2;
2.2 Nếu s[g]='0' thì d:=g
2.3 Nếu s[g]='1' thì c:=g-1;
3.Quay lại bước 3
4.Kết thúc
Vậy vị trí của số 0 cuối cùng trong dãy là d
Bài 4. HÀNG CÂY
Trong khu vườn, người ta trồng một hàng cây chạy dài gồm có N cây, mỗi cây có độ cao là a 1,
a2,…aN.
Người ta cần lấy M mét gỗ bằng cách đặt cưa máy sao cho lưỡi cưa ở độ cao H (mét) để cưa tất cả
các cây có độ cao lớn hơn H (dĩ nhiên những cây có độ cao không lớn hơn H thì không bị cưa).
Ví dụ: Nếu hàng cây có các cây với độ cao tương ứng là 20; 15; 10 và 18 mét, cần lấy 7 mét gỗ.
Lưỡi cưa đặt tại độ cao hợp lí là 15 mét thì độ cao của các cây còn lại sau khi bị cưa tương ứng là
15; 15; 10 và 15 mét. Tổng số mét gỗ lấy được là 8 mét (dư 1 mét).
Yêu cầu: Hãy tìm vị trí đặt lưỡi cưa hợp lí (số nguyên H lớn nhất) sao cho lấy được M mét gỗ và
số mét gỗ dư ra là ít nhất.
Dữ liệu:
Dòng thứ nhất chứa 2 số nguyên dương N và M (1≤N≤106; 1≤M≤2x109) cách nhau một dấu
cách.
Dòng thứ hai chứa N số nguyên dương ai là độ cao của mỗi cây trong hàng (1≤ai≤109; i=1…N),
mỗi số cách nhau ít nhất một dấu cách.
Kết quả: Đưa ra màn hình một số nguyên cho biết giá trị cần tìm.
Ví dụ:
WOOD.INP WOOD.OUT
47 15
20 15 10 18
Thuật toán :
+ Đầu=0, cuối= chiều cao cây cao nhất.
+ Kiểm tra số mét gỗ S lấy được khi chặt ở độ cao h=(đầu+cuối) div 2:
- Nếu S=M: Thì in ra h và dừng chương trình.
- Nếu S<M thì đầu =h
- Nếu S>M thì cuối =h
- Tiếp tục kiểm tra h cho đến khi chênh lệch của M,S lặp lại.
writeln('Chieu cao cua cac cay la:');
for i:=1 to n do
begin
write('cay ',i,'=');readln(a[i]);
if a[i]>c then c:=a[i];
end;
d:=0;kt:=true;
while kt and (d<=c) do
begin
s:=0;
g:=(d+c) div 2;
for i:=1 to n do
begin
t:=a[i]-g;
if t>=0 then s:=s+t;
end;
t:=s-m;
if (t=0 )or (cl=t)then kt:=false
else begin
cl:=t;
if t<0 then c:=g else d:=g;
end;
end;
if t>=0 then write('h=',g) else write('ko tim dc');