Как найти все целочисленные точки отрезка

0 / 0 / 0

Регистрация: 02.07.2021

Сообщений: 12

1

Целые точки отрезка

02.08.2021, 14:40. Показов 5611. Ответов 6


Студворк — интернет-сервис помощи студентам

Требуется написать программу, которая вычислит, сколько всего точек с целочисленными координатами принадлежат отрезку.

Входные данные
Даны четыре целых числа – координаты концов отрезка (x1, y1) и (x2, y2). Каждая из координат не превышает по абсолютной величине значения 1000.

Выходные данные
Требуется вывести количество точек отрезка, имеющих целочисленные координаты.



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

02.08.2021, 14:40

Ответы с готовыми решениями:

Расстояние от точки до отрезка
Помогите пожалуйста решить

Входные данные
Шесть чисел – координаты точки и координаты концов…

Задаются 4 переменных (x1,y1) и (x2,y2)-это крайние точки отрезка.Нужно найти все целочисленные точки принадлежащие этому отрезку на графике
Доброго времени суток.
Задаются 4 переменных (x1,y1) и (x2,y2)-это крайние точки отрезка.Нужно…

Расстояние от точки до отрезка
Дан отрезок в пространстве (x1,y1,z1) – (x2,y2,z2) и точка (x,y,z). Найдите расстояние от точки до…

Определить расположение точки относительно отрезка
Даны три точки А,В,С, лежащие на одной прямой. Определить расположение точки С относительно отрезка…

6

Cyborg Drone

Модератор

9583 / 4904 / 3243

Регистрация: 17.08.2012

Сообщений: 15,317

03.08.2021, 03:26

2

Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

Для сдачи на проверочный сайт:

Pascal
1
2
3
4
5
6
7
8
9
10
11
var
  x1, y1, x, y: integer;
begin
  readln(x1, y1, x, y);
  x := abs(x1 - x);
  y := abs(y1 - y);
  while (x <> 0) and (y <> 0) do
    if x > y then x := x mod y
    else y := y mod x;
  writeln(x + y + 1)
end.



2



nimfa2077

0 / 0 / 0

Регистрация: 02.07.2021

Сообщений: 12

03.08.2021, 11:28

 [ТС]

3

К сожалению решение не правильное,на проверочном чайте видало 1 из 36.
Смог найти другое решение, но оно тоже не верно . 15 из 36

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var
  n,x1,y1,x2,y2,k,i: integer;
  y: real;
begin
  read(x1,y1,x2,y2);
  writeln;
  i:=x1;
  while i<x2 do
  begin
    inc(i);
    y:=((i-x1)*(y2-y1))/(x2-x1)-y1;
    if frac(y)=0 then inc(k);
  end;
  write(k+1);
end.



0



1642 / 1091 / 487

Регистрация: 17.07.2012

Сообщений: 5,345

05.08.2021, 23:15

4

Цитата
Сообщение от Cyborg Drone
Посмотреть сообщение

while (x <> 0) and (y <> 0) do

А может быть or надо ? Пишу “может быть”, потому что уже сонный, мог ерунду сказать.



0



2873 / 1530 / 617

Регистрация: 19.03.2019

Сообщений: 5,111

06.08.2021, 13:40

5

Цитата
Сообщение от Новичок
Посмотреть сообщение

А может быть or надо ? Пишу “может быть”, потому что уже сонный, мог ерунду сказать.

нет.
там далее операции деления на y и на x – если одно из них будет нулевое – будет exception при делении на ноль.



0



Модератор

Эксперт по электронике

8310 / 4211 / 1600

Регистрация: 01.02.2015

Сообщений: 13,105

Записей в блоге: 4

06.08.2021, 16:33

6

У меня чувство, что эта задача на нахождение НОД.

Добавлено через 56 секунд
А из НОД нахождение количества подобных треугольников с целочисленными координатами.

Добавлено через 32 минуты
Разобрался.

Cyborg Drone, именно такое решение и предложил, только я не сразу понял как НОД вычисляется.

Всё правильно, код рабочий.



0



Cyborg Drone

Модератор

9583 / 4904 / 3243

Регистрация: 17.08.2012

Сообщений: 15,317

07.08.2021, 19:11

7

Был некоторое время занят.

nimfa2077, найденный Вами код – это неэффективное решение методом полного перебора. В этом коде есть алгоритмических ошибки:

  • Вовсе не обязательно должно быть x1 < x2, поэтому примерно в половине случаев цикл while не выполнится ни разу.
  • Если отрезок параллелен оси Y, то есть, если (x1 = x2) и (y1 ≠ y2), то результат будет неверным.
  • Не ошибка, но переменная n не используется.

Можно избавиться от вещественных операций. Поскольку y1 по условию целое, и поэтому дробная часть чисел (i-x1)*(y2-y1)/(x2-x1)-y1 и (i-x1)*(y2-y1)/(x2-x1) одна и та же, можно заменить первое число на второе, после чего заменить операцию / и функцию frac на операцию mod. Исправить можно так:

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var
  x1, y1, x2, y2, x, k: integer;
begin
  readln(x1, y1, x2, y2);
  if x1 = x2 then
    begin
      x := x1;
      x1 := y1;
      y1 := x;
      x := x2;
      x2 := y2;
      y2 := x
    end;
  if x1 > x2 then
    begin
      x := x1;
      x1 := x2;
      x2 := x;
      x := y1;
      y1 := y2;
      y2 := x
    end;
  for x := x1 + 1 to x2 do
    if (x - x1) * (y2 - y1) mod (x2 - x1) = 0 then inc(k);
  writeln(k + 1)
end.



1



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

07.08.2021, 19:11

Помогаю со студенческими работами здесь

Определить взаимное расположение на плоскости точки и отрезка
Определить взаимное расположение на плоскости
(принадлежит, не принадлежит, если не принадлежит,…

Вывести длину каждого отрезка, если известны точки их построения
Дано целое число N(&gt;1) и две вещественные точки на числовой оси: A,B (A&lt;B). Отрезок разбит на N…

Определить, находятся ли все точки отрезка по одну сторону от плоскости
Написать программу определения факта нахождения всех точек отрезка по одну сторону от плоскости.

Найти длину отрезка по данным координатам, длина до 3 знаков после точки
Найдите длину отрезка, если заданы координаты начала и конца данного отрезка. Ввести одной строке…

Указать, каким четвертям координатной плоскости принадлежат точки заданного отрезка
Даны вещественные числа x1, y1, x2, y2. Указать, каким четвертям координатной плоскости принадлежат…

Даны два отрезка [a, b], [c, d] на прямой. Установить, имеют ли они общие точки или нет
Даны два отрезка , на прямой. Установить, имеют ли они общие точки или нет.

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

7

Все целые точки на отрезке

Я ищу короткий умный способ найти все целые точки на отрезке. 2 точки также являются целыми числами, и линия может быть под углом 0,45,90,135 и т. Д. Градусов.

Вот мой длинный код (до сих пор случаи 90 градусов):

def getPoints(p1,p2)
if p1[0] == p2[0]:
    if p1[1] < p2[1]:
        return [(p1[0],x) for x in range(p1[1],p2[1])]
    else:
        return [(p1[0],x) for x in range(p1[1],p2[1],-1)]
if p2[1] == p2[1]:
    if p1[0] < p2[0]:
        return [(x,p1[1]) for x in range(p1[0],p2[0])]
    else:
        return [(x,p1[1]) for x in range(p1[0],p2[0],-1)]

РЕДАКТИРОВАТЬ: Я не упомянул это достаточно ясно, но наклон всегда будет целым числом -1, 0 или 1, есть 8 случаев, которые необходимо проверить.

2013-07-17 18:00

4
ответа

Уменьшите наклон до наименьших значений (p/q), затем переходите от одной конечной точки отрезка к другой с шагом p по вертикали и q по горизонтали. Один и тот же код может работать для вертикальных отрезков, если ваш код сокращения до минимальных сокращает 5/0 до 1/0.

2013-07-17 18:07

я мог бы написать код, который работает, но количество повторяющегося кода отталкивает меня, поэтому я обратился к вам, ребята

Это может вынести много улучшений, но, возможно, это поможет вам в этом.
(извините, сейчас нет времени, чтобы сделать это лучше!)

def points(p1,p2):
  slope = (p2[1]-p1[1])/float(p2[0]-p1[0])
  [(x,x*slope) for x in range (p1[0], p2[0]) if int(x*slope) == x*slope)]

2013-07-17 18:26

Сделайте немного математики для каждой пары точек, вычислите m & c для mx+c и сравните его с формулами для рассматриваемых линий. (NB. Вы получите некоторое деление на нули, чтобы справиться.)

2013-07-17 18:12

Расширение ответа @Jon Kiparsky.

def points_on_line(p1, p2):
    fx, fy = p1 
    sx, sy = p2 
    if fx == sx and fy == sy:
        return []
    elif fx == sx:
        return [(fx, y) for y in range(fy+1, sy)]
    elif fy == sy:
        return [(x, fy) for x in range(fx+1, sx)]
    elif fx > sx and fy > sy:
        p1, p2 = p2, p1  

    slope = (p2[1] - p1[1]) / float(p2[0] - p1[0])
    return [(x, int(x*slope)) for x in range(p1[0], p2[0]) if int(x*slope) == x*slope and (x, int(x*slope)) != p1]

2019-12-10 13:30

def getpoints(p1, p2):
  # Sort both points first.
  (x1, y1), (x2, y2) = sorted([p1, p2])
  a = b = 0.0

  # Not interesting case.
  if x1 == x2:
      yield p1

  # First point is in (0, y).
  if x1 == 0.0:
      b = y1
      a = (y2 - y1) / x2
  elif x2 == 0.0:
      # Second point is in (0, y).
      b = y2
      a = (y1 - y2) / x1
  else:
      # Both points are valid.
      b = (y2 - (y1 * x2) / x1) / (1 - (x2 / x1))
      a = (y1 - b) / x1

      for x in xrange(int(x1), int(x2) + 1):
          y = a * float(x) + b
          # Delta could be increased for lower precision.
          if abs(y - round(y)) == 0:
              yield (x, y)

2013-07-17 18:26

Сообщество Программистов

Загрузка…

uses crt;
const t=10e-10;
var x1,y1,x2,y2,x,y,kol:integer;
    k,b:real;
begin
clrscr;
writeln('Введите координаты начала отрезка, целые числа');
readln(x1,y1);
writeln('Введите координаты конца отрезка, целые числа');
readln(x2,y2);
if(x1=x2)and(y1=y2) then k:=1 {если отрезок вырожденный}
else if x1=x2 then kol:=abs(y2-y1)+1{если горизонтальный}
else if y1=y2 then kol:=abs(x2-x1)+1{если вертикальный}
else {иначе}
 begin
  if x1>x2 then{определим начало и конец по оси Х}
   begin
    x:=x1;
    x1:=x2;
    x2:=x;
   end;
  kol:=0;{количество точек с целыми координатами}
  {определим коэффициенты уравнения прямой y=kx+b}
  k:=(y2-y1)/(x2-x1);
  b:=y2+x2*k;
  {проверим все точки по Х}
  for x:=x1 to x2 do
  {если вычисленное значение дробной части практически=0, то целое}
  if abs(frac(k*x+b))<t then kol:=kol+1;
 end;
write('Количество точек с целыми коoрдинатами=',kol);
readln
end.

Добавить комментарий