Примечание: предполагается, что точки, расположенные на сторонах квадрата, принадлежат ему

Это переборная задача. Обратите внимание, что стороны квадрата могут и не быть параллельны осям координат! Каждую из N точек мы последовательно рассматриваем в качестве верхнего левого угла квадрата, каждую из оставшихся N-1 - как нижнюю правую вершины и смотрим, есть ли для них в этом множестве из N точек точки, соответствующие верхнему правому и нижнему левому углу. Если да, то подсчитываем, сколько точек лежат в данном квадрате.

Пусть координата левого верхнего угла (x1,y1), нижнего правого (x2,y2), тогда координата пересечения диагоналей четырехугольника ((x1+x2)/2,(y1+y2)/2); координата верхнего правого угла

((x1+x2)/2+[y1-(y1+y2)/2],(y1+y2)/2+[x1-(x1+x2)/2])= =((x1+x2+y1-y2)/2, (x1-x2+y1+y2)/2), нижнего левого - ((x1+x2-y1+y2)/2,(-x1+x2+y1+y2)/2)

(Постройте чертеж и проверьте!).

Для (x1,y2) и (x2,y2) должны выполняться следующие неравенства: x1<=x2, y1>=y2 (иначе это будут уже не левый верхний и правый нижний углы квадрата).

Программа:

{В исходном множестве поочередно перебираются все пары точек.}{Предполагая, что отрезок, соединяющий эти точки, является ребром}{квадрата строим квадрат и смотрим, все ли его вершины имеются в}{исходном множестве. Если все, то определяем, сколько точек из}{исходного множества лежит внутри этого квадрата. Если это число}{превосходит старый рекорд то запоминаем найденный квадрат.}{ }{$A-,B-,D-,E+,F-,I+,L-,N-,O-,R-,S-,V-}{$M 65520,0,655360}uses crt;constmaxn = 100;{ Максимальное число точек }type xy = record x,y: real end; { Тип для записи координат точек }var m: array[1..maxn] of xy; { Координаты точек множества } i,j,g,k,n,p: word; { вспомогательные переменные } num: word; { для записи числа точек в текущем квадрате } rec: word; { для записи числа точек в лучшем квадрате } a1,b1,c1: real; { вспомогательные переменные } r,c: array[1..5] of xy;{ для записи вершин квадратов } f1,f2: boolean; o: array[1..4] of shortint;Function sign(a: real): shortint;{ Функция signum }begin if a<0 then sign:=-1 else if a>0 then sign:=1 else sign:=0end;{ нахождение коэффициентов прямой, проходящей через точки x1,y1 и x2,y2 }procedure getabc(x1,y1,x2,y2:real; var a,b,c:real);begina:=y2-y1; b:=x1-x2; c:=-(a*x1+b*y1)end;begin write('Введите число точек...'); readln(n); for i:=1 to n do begin write('Введите координаты ',i,'-ой точки...'); readln(m[i].x,m[i].y); end; rec:=0;{ Обнуление рекорда }for i:=1 to n do { Перебор всех квадратов, для которых отрезок m[i]-m[j] } for j:=1 to n do { является ребром } if i<>j then beginc[1]:=m[i]; c[2]:=m[j]; { Определение вершин квадрата } c[3].x:=c[2].x+(c[1].y-c[2].y); c[3].y:=c[2].y+(c[2].x-c[1].x); c[4].x:=c[1].x+(c[1].y-c[2].y); c[4].y:=c[1].y+(c[2].x-c[1].x); c[5]:=c[1]; num:=0;{ Проверка на наличие всех вершин квадрата в исходном множестве точек }f1:=false; f2:=false; for g:=1 to n do if (m[g].x=c[3].x) and (m[g].y=c[3].y) then f1:=true; for g:=1 to n do if (m[g].x=c[4].x) and (m[g].y=c[4].y) then f2:=true; if (c[1].x=c[2].x) and (c[1].y=c[2].y) then f1:=false;if f1 and f2 then {Если все вершины квадрата есть в исходном множестве}for k:=1 to n do { то определяем число точек в квадрате} begin for g:=1 to 4 do begingetabc(c[g].x,c[g].y,c[g+1].x,c[g+1].y,a1,b1,c1); o[g]:=sign(a1*m[k].x+b1*m[k].y+c1); end; if ((o[1]=o[2]) and (o[2]=o[3]) and (o[3]=o[4])) or((o[1]=o[2]) and (o[2]=o[3]) and (o[4]=0)) or ((o[1]=o[2]) and (o[2]=o[4]) and (o[3]=0)) or ((o[1]=o[3]) and (o[3]=o[4]) and (o[2]=0)) or ((o[2]=o[3]) and (o[3]=o[4]) and (o[1]=0)) or ((m[k].x=c[1].x) and (m[k].y=c[1].y)) or ((m[k].x=c[2].x) and (m[k].y=c[2].y)) or ((m[k].x=c[3].x) and (m[k].y=c[3].y)) or ((m[k].x=c[4].x) and (m[k].y=c[4].y)) then inc(num); end; if rec<num then begin r:=c; rec:=num end; end; if rec=0 then { Не найдено ни одного квадрата } begin writeln('Не найдено ни одного квадрата.'); halt end; { Вывод результатов } write('Лучший квадрат: ');for i:=1 to 3 do write('(',r[i].x:2:2,

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: