program Slunce; const MAXB=200; type Bod = record x,y : Real; end; PoleBodu = Array[1..MAXB] of Bod; PoleMna = Array[1..MAXB] of Integer; Kruznice = record x, y, r : Real; end; var Bodu : Integer; {Počet bodů} Body : PoleBodu; {Pole s body} V, H : PoleMna; {Pole se seznamem bodu patřících do množiny V a H} VN, HN : Integer; {Počty prvků v množinách V a H} K : Kruznice; {Výsledná nejmenší kružnice} {Inicializace} procedure Init; var i : Integer; begin Write('Pocet bodu: '); ReadLn(Bodu); for i := 1 to Bodu do begin Write('Souradnice: '); ReadLn(Body[i].x, Body[i].y); end; HN := 0; VN := Bodu; for i := 1 to Bodu do V[i] := i; end; {Vytvoří kružnici obsahující dané body na hranici} function ProlozKruznici(N : Integer; var B : PoleMna) : Kruznice; var K : Kruznice; s, t : Real; U, V : Bod; begin if N <= 1 then begin K.x := 0; K.y := 0; K.r := 0; end else if N = 2 then begin K.x := (Body[B[1]].x+Body[B[2]].x)/2; K.y := (Body[B[1]].y+Body[B[2]].y)/2; K.r := sqrt(sqr(Body[B[1]].x-Body[B[2]].x)+sqr(Body[B[1]].y-Body[B[2]].y))/2; end else begin {Spočteme střed kružnice opsané} U.x := Body[B[2]].x-Body[B[1]].x; U.y := Body[B[2]].y-Body[B[1]].y; V.x := Body[B[2]].x-Body[B[3]].x; V.y := Body[B[2]].y-Body[B[3]].y; {Alespoň jedno z čísel U.x a U.y bude nenulové} if U.x <> 0 then begin s := ((Body[B[1]].x-Body[B[3]].x)/2-U.y/U.x*(Body[B[3]].y-Body[B[1]].y)/2)/(U.y*V.x/U.x-V.y); K.x := (Body[B[2]].x+Body[B[3]].x)/2-s*V.y; K.y := (Body[B[2]].y+Body[B[3]].y)/2+s*V.x; end else begin t := ((Body[B[1]].x-Body[B[3]].x)/2+V.y/V.x*(Body[B[1]].y-Body[B[3]].y)/2)/(U.y-V.y*U.x/V.x); K.x := (Body[B[2]].x+Body[B[1]].x)/2-t*U.y; K.y := (Body[B[2]].y+Body[B[1]].y)/2+t*U.x; end; K.r := sqrt(sqr(K.x-Body[B[1]].x)+sqr(K.y-Body[B[1]].y)); end; ProlozKruznici := K; end; {Zjistí, zda daný bod leží uvnitř kružnice} function LeziUvnitr(K : Kruznice; B : Integer) : Boolean; begin if sqr(K.x-Body[B].x)+sqr(K.y-Body[B].y) <= sqr(K.r) then LeziUvnitr := True else LeziUvnitr := False; end; {Základní rekurzivní funkce} function MinKruh(VN, HN : Integer; var V, H : PoleMna) : Kruznice; var K : Kruznice; VBodI, VBod : Integer; {Vybraný bod k vypuštění} begin if VN = 0 then MinKruh := ProlozKruznici(HN, H) else begin VBodI := Trunc(Random*(VN-1)) + 1; VBod := V[VBodI]; V[VBodI] := V[VN]; Dec(VN); K := MinKruh(VN, HN, V, H); if not LeziUvnitr(K, VBod) then begin Inc(HN); H[HN] := VBod; K := MinKruh(VN, HN, V, H); Dec(HN); end; {Vrátíme pole do původního stavu} Inc(VN); V[VN] := V[VBodI]; V[VBodI] := VBod; {Vrátíme výsledek} MinKruh := K; end; end; begin Init; K := MinKruh(VN, HN, V,H); WriteLn('Souradnice stredu: ', K.x:2:2, ' ', K.y:2:2); WriteLn('Polomer: ', K.r:2:2); end.