Из двух заданных множеств точек на плоскости выбрать четыре различные точки по условию (массивы)
09.01.2016, 14:54. Показов 1414. Ответов 0
Задача:
Даны два множества точек на плоскости. Выбрать четыре различные точки первого множества так, чтобы квадрат с вершинами в этих точках накрывал все точки
второго множества и имел минимальную площадь.
Нашёл подобную задачу с решением,но там дан треугольник. Переделал под квадрат, но теперь программа не выдаёт площадь и пишет только:
"Не найдено точек, чтобы покрыть квадратом всё второе множество!"
Помогите, пожалуйста. Уже голова кругом.
Вот исходник:
| C++ | 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
| #include <iostream>
#include <ctime>
#include <cmath>
#include <conio.h>
using namespace std;
int **first_arr, **second_arr; //множества точек
bool unique(int x, int y, int **arr, int n)//проверяем,является ли точка единственной в множестве
{
for (int i = 0; i < n; i++)
{
if (arr[0][i] == x && arr[1][i] == y)
return false;
}
return true;
}
void generate_arr(int n, int m)
{
srand(time(0));
first_arr = new int*[2];
second_arr = new int*[2];
first_arr[0] = new int [n];
second_arr[0] = new int[m];
first_arr[1] = new int[n];
second_arr[1] = new int[m];
int x, y;
for (int j = 0; j < n; j++)
{
do
{
x = rand() % 100;
y = rand() % 100;
} while (!unique(x, y, first_arr, n));
first_arr[0][j] = x;
first_arr[1][j] = y;
}
for (int j = 0; j < m; j++)
{
do
{
x = rand() % 100;
y = rand() % 100;
} while (!unique(x, y, second_arr, m));
second_arr[0][j] = x;
second_arr[1][j] = y;
}
}
void show_arr(int n, int m)
{
cout << "Первое множество :\n";
for (int i = 0; i < n; i++)
cout << (i + 1) << ") x = " << first_arr[0][i] << ", y = " << first_arr[1][i] << endl;
cout << "\nВторое множество :\n";
for (int i = 0; i < m; i++)
cout << (i + 1) << ") x = " << second_arr[0][i] << ", y = " << second_arr[1][i] << endl;
}
bool isTriangle(double a, double b, double c)//проверяем, являются ли отрезки треугольником
{
if ((a + b - c < 0) || (a + c - b < 0) || (b + c - a < 0))
return false;
return true;
}
double square(double a, double b, double c)
{
return sqrt((a + b + c) * (b + c - a) * (a + c - b) * (a + b - c)) / 4.0;
}
double distanceBetweenPoints(int x1, int y1, int x2, int y2)
{
double d = 0;
d = (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);
return sqrt(d);
}
int area(int x1, int y1, int x2, int y2, int x3, int y3)
{
return abs((x1 - x3)*(y2 - y3) + (x2 - x3)*(y3 - y1));
}
bool checkFirstCoversSecond(int x1, int y1, int x2, int y2, int x3, int y3, int **arr, int m)
{
for (int i = 0; i < m; i++)
{
if (!(area(x1, y1, x2, y2, x3, y3) == area(x1, y1, x2, y2, arr[0][i], arr[1][i]) + area(x1, y1, arr[0][i], arr[1][i], x3, y3) + area(x2, y2, arr[0][i], arr[1][i], x3, y3)))
return false;
}
return true;
}
double min_square(int **arr, int n, int m)
{
double a, b, c; //стороны нашего треугольника
double minS = DBL_MAX;
double S;
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
for (int z = j + 1; z < n; z++)
{
if (checkFirstCoversSecond(arr[0][i], arr[1][i], arr[0][j], arr[1][j], arr[0][z], arr[1][z], second_arr, m))
{
a = distanceBetweenPoints(arr[0][i], arr[1][i], arr[0][j], arr[1][j]);
b = distanceBetweenPoints(arr[0][i], arr[1][i], arr[0][z], arr[1][z]);
c = distanceBetweenPoints(arr[0][z], arr[1][z], arr[0][j], arr[1][j]);
if (isTriangle(a, b, c))
{
S = square(a, b, c);
cout << "\nТочки - (" << arr[0][i] << ", " << arr[1][i] << ")-(" << arr[0][j] << ", " << arr[1][j] << ")-(" << arr[0][z] << ", " << arr[1][z] << ") --- накрывают все точки второго множества!\n";
cout << "Площадь треугольника с вершинами в этих точках = " << S << endl;
if (S < minS) { minS = S; }
}
else
{
cout << "Не являются треугольником!!!\n";
}
}
}
if (minS != DBL_MAX)
cout << "\n\nМинимальную площадь = " << minS << endl;
else
cout << "\n\nНе найдено точек, чтобы покрыть треугольником всё второе множество!" << endl;
return 0;
}
void main()
{
setlocale(LC_ALL, "Russian");
int n, m; //количество точек в множествах
cout << "Введите количество точек первого множества - ";
cin >> n;
cout << "Введите количество точек второго множества - ";
cin >> m;
generate_arr(n, m);
show_arr(n, m);
min_square(first_arr, n, m);
getch();
} |
|
Вот исправленная:
| C++ | 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
| #include <iostream>
#include <ctime>
#include <cmath>
#include <conio.h>
using namespace std;
int **first_arr, **second_arr; //множества точек
bool unique(int x, int y, int **arr, int n)//проверяем, является ли точка единственной в множестве
{
for (int i = 0; i < n; i++)
{
if (arr[0][i] == x && arr[1][i] == y)
return false;
}
return true;
}
void generate_arr(int n, int m)
{
first_arr = new int*[2];
second_arr = new int*[2];
first_arr[0] = new int [n];
second_arr[0] = new int[m];
first_arr[1] = new int[n];
second_arr[1] = new int[m];
int x, y;
for (int i = 0; i < n; i++)
{
cout << "x[" << i+1 << "]=";
cin >> first_arr[0][i];
cout << "y[" << i+1 << "]=";
cin >> first_arr[1][i];
}
cout<<endl<<endl;
for (int i = 0; i < m; i++)
{
cout << "x[" << i+1 << "]=";
cin >> second_arr[0][i];
cout << "y[" << i+1 << "]=";
cin >> second_arr[1][i];
}
cout<<endl<<endl;
}
void show_arr(int n, int m)
{
cout << "Первое множество:\n";
for (int i = 0; i < n; i++)
cout << (i + 1) << ") x = " << first_arr[0][i] << ", y = " << first_arr[1][i] << endl;
cout << "\nВторое множество:\n";
for (int i = 0; i < m; i++)
cout << (i + 1) << ") x = " << second_arr[0][i] << ", y = " << second_arr[1][i] << endl;
}
bool isTriangle(double a, double b, double c, double d)//являются ли отрезки квадратом
{
if (!((a == b) || (b == c) || (c == d) || (d == a)))
return false;
return true;
}
double square(double a, double b, double c, double d)//площадь квадрата через стороны
{
return sqrt((a+b+c-d)*(a+b+d-c)*(a+c+d-b)*(b+c+d-a))/4;
}
double distanceBetweenPoints(int x1, int y1, int x2, int y2)//расстояние между точками
{
double D = 0;
D = (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);
return sqrt(D);
}
int area(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)//площадь через координаты вершин
{
return ((x1 - x2)*(x3 - x4) + (y1 - y2)*(y3 - y4)); //???????
}
bool checkFirstCoversSecond(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int **arr, int m)
{
for (int i = 0; i < m; i++)
{
if (!(area(x1, y1, x2, y2, x3, y3, x4, y4) == area(x1, y1, x2, y2, arr[0][i], arr[1][i], x4, y4) + area(x1, y1, arr[0][i], arr[1][i], x3, y3, x4, y4) + area(x2, y2, arr[0][i], arr[1][i], x3, y3, x4, y4)+area(x1, y1, x2, y2, x3, y3, arr[0][i], arr[1][i])))
return false;
}
return true;
}
double min_square(int **arr, int n, int m)
{
double a, b, c, d;
double minS = DBL_MAX;
double S;
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
for (int z = j + 1; z < n; z++)
for (int k = z + 1; k < n; k++)
{
if (checkFirstCoversSecond(arr[0][i], arr[1][i], arr[0][j], arr[1][j], arr[0][z], arr[1][z], arr[0][k], arr[1][k], second_arr, m))
{
a = distanceBetweenPoints(arr[0][i], arr[1][i], arr[0][j], arr[1][j]);
b = distanceBetweenPoints(arr[0][j], arr[1][j], arr[0][k], arr[1][k]);
c = distanceBetweenPoints(arr[0][k], arr[1][k], arr[0][z], arr[1][z]);
d = distanceBetweenPoints(arr[0][z], arr[1][z], arr[0][i], arr[1][i]);
if (isTriangle(a, b, c, d))
{
S = square(a,b,c,d);
cout << "\nТочки - (" << arr[0][i] << ", " << arr[1][i] << ")-(" << arr[0][j] << ", " << arr[1][j] << ")-(" << arr[0][z] << ", " << arr[1][z] << ")-(" << arr[0][k] << ", " << arr[1][k] << ") --- накрывают все точки второго множества!\n";
cout << "Площадь квадрата с вершинами в этих точках = " << S << endl;
if (S < minS) { minS = S; }
}
else
{
cout << "Не являются Квадратом!!!\n";
}
}
}
if (minS != DBL_MAX)
cout << "\n\nМинимальную площадь = " << minS << endl;
else
cout << "\n\nНе найдено точек, чтобы покрыть квадратом всё второе множество!" <<endl;
return 0;
}
void main()
{
setlocale(LC_ALL, "Russian");
int n, m;
cout << "Введите количество точек первого множества - ";
cin >> n;
cout << "Введите количество точек второго множества - ";
cin >> m;
generate_arr(n, m);
show_arr(n, m);
min_square(first_arr, n, m);
getch();
} |
|
0
|