Помощь - Поиск - Пользователи - Календарь
Полная версия: Расстояние между точками
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
kent
Помогите с задачей... Дано множество А из N точек. Найти пару различных точек этого множества с минимальным|максимальным расстоянием между ними и само это расстояние(точки выводятся в том же порядке, в котором они перечислены при задании множества А). Мое решение получилось большим, но не это главное, в нем идет дублирование координат...

uses crt;
var a : array [1..1000] of Integer;
    temp : array [1..1000] of Integer;
    dif : array [1..1000] of Integer;
    id_1 : array [1..1000] of Integer;
    id_2 :array [1..1000] of Integer;
    N,m,i,j : Integer;
    indx, count_indx : Integer;
    min,sec_min,id_min : Integer;
    max,sec_max,id_max : Integer;
    id_near_x1,id_near_x2 : Integer;
    id_near_y1,id_near_y2 : Integer;
    id_far_x1,id_far_x2 : Integer;
    id_far_y1,id_far_y2 : Integer;
    near_x1,near_x2 : Integer;
    near_y1,near_y2 : Integer;
    far_x1,far_x2 : Integer;
    far_y1, far_y2 : Integer;
    space_near, space_far : Real;

{----------------------------------------}
{Функция вычисления количества сочетаний}

Function Range(a,b : Integer) : Extended;
var p1,p2,p3 : Integer;
    fac_a,fac_b,fac_dif : Extended;
begin
     fac_a := 1; p1 := 1;
     repeat
       inc(p1);
       fac_a := fac_a * p1;
     until p1 = a;
     fac_b := 1; p2 := 1;
     repeat
       inc(p2);
       fac_b := fac_b * p2;
     until p2 = b;
     fac_dif := 1; p3 := 1;
     repeat
       inc(p3);
       fac_dif :=fac_dif * p3;
     until p3 = a - b;
     Range := fac_a/(fac_b * fac_dif);
end;
{----------------------------------------}

begin
     {$R+}
     Clrscr;
     Write('Input N:');
     ReadLn(N);
     Write('Input set N:');
     for i := 1 to N do begin
        Read(a[i]);
        temp[i] := a[i];
     end;
     m := 2;
     for i := 1 to m do a[i] := i;
     indx := 0;
     repeat
       inc(indx);
       for i := 1 to m do
          if (i > 1) then begin
            id_1[indx] := a[i - 1];
            id_2[indx] := a[i];
          end;
         dif[indx] := abs(temp[id_1[indx]] - temp[id_2[indx]]);
       i := m;
       while (i > 1) and (a[i] = N - m + i) do dec(i);
       inc(a[i]);
       for j := i + 1 to m do a[j] := a[j - 1] + 1;
     until (i = 0) or (indx = 1000) or (indx = Range(N,m));
     count_indx := indx;
     min := Maxint; sec_min := Maxint;
     max := -32768; sec_max := -32768;
     for indx := 1 to count_indx do begin
        if (dif[indx] < min) then begin
          id_min := indx;
          min := dif[indx];
          id_near_x1 := id_1[indx];
          id_near_x2 := id_2[indx];
        end;
        if (dif[indx] > max) then begin
          id_max := indx;
          max := dif[indx];
          id_far_x1 := id_1[indx];
          id_far_x2 := id_2[indx];
        end
     end;
     for indx := 1 to count_indx do begin
        if (dif[indx] < sec_min) and (indx <> id_min) then begin
          sec_min := dif[indx];
          id_near_y1 := id_1[indx];
          id_near_y2 := id_2[indx];
        end;
        if (dif[indx] > sec_max) and (indx <> id_max) then begin
          sec_max := dif[indx];
          id_far_y1 := id_1[indx];
          id_far_y2 := id_2[indx];
        end;
     end;
     for i :=1 to N do begin
        if (i = id_near_x1) then
          near_x1 := temp[i]
        else if (i = id_near_x2) then
          near_x2 :=temp[i];
        if (i = id_near_y1) then
          near_y1 := temp[i]
        else if (i = id_near_y2) then
          near_y2 := temp[i];
        if (i = id_far_x1) then
          far_x1 := temp[i]
        else if (i = id_far_x2) then
          far_x2 := temp[i];
        if (i = id_far_y1) then
          far_y1 := temp[i]
        else if (i = id_far_y2) then
          far_y2 := temp[i];
     end;
     space_near := sqrt(sqr(abs(near_x1 - near_x2)) + sqr(abs(near_y1 - near_y2));
     space_far := sqrt(sqr(abs(far_x1 - far_x2)) + sqr(abs(far_y1 - far_y2)));
     WriteLn;
     WriteLn('Nearest points:',' (',near_x1,',',near_y1,')','-','(',near_x2,',',near_y2,');');
     WriteLn('Nearest space:',space_near,';');
     WriteLn('--------------------------------------');
     WriteLn('Farthest points:',' (',far_x1,',',far_y1,')','-','(',far_x2,',',far_y2,');');
     WriteLn('Farthest points:',space_far,';');
     Readkey;
end.



Может испраить что-нибудь можно, или вообще другой алгоритм использовать?
volvo
blink.gif Это все зачем?
Проще надо делать, не нужно усложнять:
{$n+}
type
  TPoint = record
    X, Y: integer;
  end;
function dist(a, b: TPoint): double;
begin
  dist := sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
end;

var
  A: array[1 .. 1000] of TPoint;
  i, j, N: Integer;
  min_dist, max_dist, curr_dist: double;
  max_first, max_second,
  min_first, min_second: integer;
begin
  { вводим число N }
  { вводим координаты N точек:}
  for i := 1 to n do begin
    write('точка №', i, ': X ='); readln(a[i].X);
    write('Y ='); readln(a[i].Y);
  end;

  min_dist := 100000;
  max_dist := 0;
  for i := 1 to N-1 do
    for j := i+1 to N do begin

      curr_dist := dist(a[i], a[j]);
      if curr_dist < min_dist then begin
        min_first := i; min_second := j; min_dist := curr_dist;
      end;
      if curr_dist > max_dist then begin
        max_first := i; max_second := j; max_dist := curr_dist;
      end;

    end;

  writeln('макс. расстояние: (между', max_first, ' и ', max_second, ') = ', max_dist);
  writeln('мин. расстояние: (между', min_first, ' и ', min_second, ') = ', min_dist);
end.
kent
smile.gif Честно говоря не знал что элемент массива можно задавать в виде двух цифр, а то бы с самого начала так и сделал...
Спасибо, volvo, ты как всегда выручаешь. :thanks:
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.