Загрузка [MathJax]/jax/output/HTML-CSS/fonts/TeX/fontdata.js

Подразделы

Другие разделы

Дата и время

14/03/2025 17:26:07

Авторизация

Имя:
Пароль:
Зарегистрироваться
Восстановить пароль
 

print4. Треугольники

Сложная задача, необходимо знание алгоритма быстрой сортировки.
Сначала докажем, что треугольник с целочисленными координатами вершин равносторонним быть не может. Площадь равностороннего треугольника равна a2 , где a – длина стороны. Для вершин с целыми координатами a^2 будет целым, следовательно площадь равностороннего будет выражаться иррациональным числом. Площадь многоугольника с целочисленными координатами вершин может быть вычислена по формуле Пика как p\ +\ q/2\ -\ 1, где p – количество точек с целочисленными координатами внутри многоугольника, а q – на границе многоугольника, включая вершины. Площадь треугольника с целочисленными координатами вершин будет рациональным числом. Получили противоречие, следовательно, можно при решении задачи не рассматривать равносторонние треугольники.
Возьмем какую-нибудь точку из заданного множества и отсортируем остальные вершины по квадрату расстояния до нее. Для сортировки необходимо использовать быструю сортировку со временем работы O(N\ log\ N). Если существует k точек, лежащих на одинаковом расстоянии от выбранной точки, то из них можно составить {k*(k-1)}/2 равнобедренных треугольников. Из этого количества нужно вычесть вырожденные треугольники, образованные центрально-симметричными точками относительно выбранной. Для этого либо сравниваем попарно положения точек, лежащих на одинаковом расстоянии от выбранной (сложность такого сравнения O(N^2), но из-за геометрической основы задачи общее количество таких сравнений будет небольшим и общее время работы алгоритма не ухудшится), либо отсортировать после ввода все точки по x, затем по y и выполнять поиск центрально-симметричной точки относительно выбранной точки для всех остальных точек за время O(log\ N).
Такие действия необходимо выполнить для всех точек, время работы алгоритма с использованием двух сортировок равно O(N^2\ log\ N). Основная часть решения выглядит так:
var N,i,j,k,m,jj:longint;
  x,y:array[1..1500] of longint;
  d:array[1..1500] of record d:int64;x,y:longint; end;;
  res:int64;
...
  { ввод данных }
  readln(N);
  for i:=1 to N do
    readln(x[i],y[i]);
  res:=0;
  for i:=1 to N do
  begin
    { заполняем массив с расстояниями и относительными координатами }
    k:=0;
    for j:=1 to N do
      if i<>j then
      begin
        inc(k);
        d[k].d:=sqr(int64(x[i]-x[j]))+sqr(int64(y[i]-y[j]));
        d[k].x:=x[j]-x[i];
        d[k].y:=y[j]-y[i];
      end;
    { сортировка }
    qsort(1,k);
    j:=1;
    while j<=k do
    begin
      { считаем количество точек на одинаковом расстоянии }
      m:=1;
      while (j+m<=k) and (d[j].d=d[j+m].d) do
      begin
        { вычитаем вырожденные треугольники }
        for jj:=j to j+m-1 do
          if (d[j+m].x=-d[jj].x) and (d[j+m].y=-d[jj].y) then
            dec(res);
        inc(m);
      end;
      res:=res+m*(m-1) div 2;
      j:=j+m;
    end;
  end;
  writeln(res);
loading