Thứ Hai, 16 tháng 12, 2013

Đoạn gối 2



Cho N đoạn thẳng trên trục số với các điểm đầu ai và điểm cuối bi là những số nguyên trong khoảng -1000..1000, ai < bi. Liệt kê tối đa K đoạn thẳng gối nhau liên tiếp.

DOAN.INP
DOAN.OUT
Dữ liệu vào: tệp văn bản DOAN.INP: xem Đoạn gối 1
Dữ liệu ra: tệp văn bản DOAN.OUT
Dòng đầu tiên: số tự nhiên K.
Tiếp đến là K dòng, mỗi dòng chứa một số tự nhiên biểu thị chỉ số của đoạn thẳng gối nhau liên tiếp trong dãy tìm được.
Thí dụ này cho biết tối đa có 3 đoạn  2,  4 và 5 tạo thành dãy đoạn gối nhau liên tiếp.


5
2 7
1 3
7 9
3 4
4 5

3
2
4
5

Thuật toán

Tương tự như bài Đoạn gối 1 nhưng cần tạo thêm con trỏ trước. t[i] = j có nghĩa là đoạn i được gối sau đoạn j. Thủ tục GiaiTrinh(i) liệt kê các đoạn gối liên tiếp từ phải qua trái thực chất là liệt kê theo chiều ngược các phần tử trong mảng con trỏ trước t bắt đầu từ phần tử thứ i. Giả sử t có dạng sau,
t[2] = 0; t[4] = 2; t[5] = 4;
và giả sử i = 5 là vị trí đạt trị cmax, ta phải ghi vào file kết quả g dãy các đoạn gối nhau liên tiếp như sau,
2 4 5
Ta chỉ việc gọi đệ quy muộn như sau
0
0
1
2
3
4
5



0

2
4
 procedure GiaiTrinh(i: integer);
 begin
  if (i <> 0) then
    begin GiaiTrinh(t[i]); writeln(g,d[i].id); end;
 end;
Độ phức tạp: cỡ  N2.
(*  Pascal  *)
(*=============================================
   Doan Goi 2: Liet ke toi da cac doan thang
                 goi nhau liên tiep
  =============================================*)
program DoanGoi2;
uses crt;
const
  mn = 1001; bl = #32; nl = #13#10;
  fn = 'doan.inp'; gn = 'doan.out';
type
  KieuDoan = record a,b,id: integer; end;
  md1 = array[0..mn] of KieuDoan;
  mi1 = array[0..mn] of integer;
var n,m: integer; { n - so luong doan, m - so doan duoc chon }
    d: md1; // cac doan
    f,g: text;
    c: mi1; { c[i] = so luong max doan goi voi doan i }
    t: mi1; { tro truoc }
procedure Doc: tự viết
procedure Qsort(i1,i2: integer): tự viết
procedure XuLi;
var i,j,jmax: integer;
begin
  fillchar(t,sizeof(t),0); {Khởi trị mảng trỏ trước}
  c[1] := 1;
  for i := 2 to n do
    begin
      c[i] := 0; jmax := i;
        for j := i-1 downto 1 do
          begin
            if (d[j].b < d[i].a) then break;
            if (d[j].b = d[i].a) then
               if (c[j] > c[jmax]) then jmax := j;
          end;
      c[i] := c[jmax]+1; t[i] := jmax;
    end;
end;
procedure GiaiTrinh(i: integer): tự viết;
procedure Ket;
var i,imax: integer;
begin
  assign(g,gn);rewrite(g);
  imax := 1;
  for i := 2 to n do
    if (c[imax] < c[i]) then imax := i;
  writeln(g,c[imax]);
  GiaiTrinh(imax);
  close(g);
end;
BEGIN
  Doc; Qsort(1,n); XuLi; Ket; 
END.


Nguồn:

SÁNG TẠO
TRONG THUẬT TOÁN
LẬP TRÌNH


Không có nhận xét nào:

Đăng nhận xét