"1stpm90", попробуйте потестировать следующий эскизный код для обнаружения
совпадения ломаных. Молчаливо предполагается, что данные вводятся
без ошибок и ломаные не замкнуты (это так?), иначе программа грохнется.
Обычно для таких задач такое требование соблюдается.
В случае проблем - будем устранять "дрова", в случае их отсутствия -
займемся разбором, комментариями, оптимизацией и другими полезными
вещами...
Код:
#include <memory.h>
#include <string.h>
#include <iostream>
using namespace std;
struct decart
{
int x;
int y;
};
int cos4[] = {1, 0, -1, 0};
int sin4[] = {0, 1, 0, -1};
int n1, n2;
struct decart *line1, *line2, *nline1, *nline2;
// true, если три точки образуют прямую линию
bool isline(struct decart *p)
{
return (p[0].x * p[1].y + p[1].x * p[2].y + p[2].x * p[0].y) -
(p[0].y * p[1].x + p[1].y * p[2].x + p[2].y * p[0].x) == 0;
}
// В списке отрезков 'src' длиной cnt найти соприкасаемый с
// текущей строящейся ломаной отрезок
// (априори считаем, что данные введены без
// ошибок, поэтому такой отрезок всегда находим)
// (x0,y0) - координаты началa текущей ломаной
// (x1,y1) - координаты конца текущей ломаной
//
// return: true - присоединение найденного отрезка слева
// false - присоединение найденного отрезка справа
// Новые координаты слева или справа возвращаются через 'result'
bool isleft(struct decart *src, int x0, int y0, int x1, int y1, struct decart *result, int cnt)
{
bool left;
struct decart *begin;
left = true;
begin = src;
for(;;)
{
if(src[0].x == x0 && src[0].y == y0)
{
result[0] = src[1];
break;
}
if(src[0].x == x1 && src[0].y == y1)
{
result[0] = src[1];
left = false;
break;
}
if(src[1].x == x0 && src[1].y == y0)
{
result[0] = src[0];
break;
}
if(src[1].x == x1 && src[1].y == y1)
{
result[0] = src[0];
left = false;
break;
}
src += 2;
}
memmove(src, src + 2, (cnt * 2 - 2 - (src - begin)) * sizeof(struct decart));
return(left);
}
// Склеивание отдельных отрезков в сплошную ломаную
int sort_line(struct decart *src, struct decart *dest, int cnt)
{
struct decart *begin, tmp;
begin = dest;
dest[0] = src[0];
dest[1] = src[1];
dest += 2;
src += 2;
while(--cnt)
{
if(isleft(src, begin[0].x, begin[0].y, dest[-1].x, dest[-1].y, &tmp, cnt))
{
memmove(begin + 1, begin, (dest - begin) * sizeof(struct decart));
begin[0] = tmp;
}
else
{
dest[0] = tmp;
}
++dest;
}
return(dest - begin);
}
// Выбросить среднюю точку из трех точек, если эти
// три точки располагаются на одной линии
int del_punkt(struct decart *p, int cnt)
{
int i;
struct decart *tmp;
bool yes_delete;
do
{
yes_delete = false;
for(tmp = p,i = cnt - 2; i; --i,++tmp)
{
if(isline(tmp))
{
memmove(tmp + 1, tmp + 2, (cnt - 2 - (tmp - p)) * sizeof(struct decart));
--cnt;
yes_delete = true;
break;
}
}
} while(yes_delete);
return(cnt);
}
bool eq_line(struct decart *line1, struct decart *line2, int cnt, int step)
{
int i, j, k, x, y;
for(i = 0; i < 4; ++i)
{
for(j = k = 0; j < cnt; ++j,k += step)
{
x = line1[k].x * cos4[i] + line1[k].y * sin4[i];
y = -line1[k].x * sin4[i] + line1[k].y * cos4[i];
if(line2[k].x != x || line2[k].y != y)
break;
}
if(j == cnt)
return(true);
}
return(false);
}
void input_date(void)
{
int i;
cout << "?";
cin >> n1 >> n2;
line1 = new struct decart[n1 * 2];
line2 = new struct decart[n2 * 2];
nline1 = new struct decart[n1 + 1];
nline2 = new struct decart[n2 + 1];
for(i = 0; i < n1 * 2; ++i)
{
cin >> line1[i].x >> line1[i].y;
}
for(i = 0; i < n2 * 2; ++i)
{
cin >> line2[i].x >> line2[i].y;
}
}
void eoj(char c)
{
delete[] line1;
delete[] line2;
delete[] nline1;
delete[] nline2;
cout << c << '\n';
}
int main(int argc, char* argv[])
{
int i, x1, x2, y1, y2;
input_date();
n1 = sort_line(line1, nline1, n1);
n2 = sort_line(line2, nline2, n2);
n1 = del_punkt(nline1, n1);
n2 = del_punkt(nline2, n2);
if(n1 != n2)
{
eoj('0');
return(0);
}
// Сдвиг по левому краю
x1 = nline1[0].x;
y1 = nline1[0].y;
x2 = nline2[0].x;
y2 = nline2[0].y;
for(i = 0; i < n1; ++i)
{
nline1[i].x -= x1;
nline1[i].y -= y1;
nline2[i].x -= x2;
nline2[i].y -= y2;
}
if(eq_line(nline1 + 1, nline2 + 1, n1 - 1, +1))
{
eoj('1');
return(0);
}
// Сдвиг по правому краю
x1 = nline1[n1 - 1].x;
y1 = nline1[n1 - 1].y;
for(i = 0; i < n1; ++i)
{
nline1[i].x -= x1;
nline1[i].y -= y1;
}
if(eq_line(nline1 + n1 - 2, nline2 + n1 - 2, n1 - 1, -1))
{
eoj('1');
return(0);
}
eoj('0');
return 0;
}