| Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
The figure shown on the left is left-right symmetric as it is possible to fold the sheet of paper along a vertical line, drawn as a dashed line, and to cut the figure into two identical halves. The figure on the right is not left-right symmetric as it is impossible to find such a vertical line.
Write a program that determines whether a figure, drawn with dots, is left-right symmetric or not. The dots are all distinct.
Input
The input consists of T test cases. The number of test cases T is given in the first line of the input file. The first line of each test case contains an integer N , where N ( 1
N
1, 000) is the number of dots in a figure. Each of the following N lines contains the x-coordinate and y-coordinate of a dot. Both x-coordinates and y-coordinates are integers between -10,000 and 10,000, both inclusive.
Output
Print exactly one line for each test case. The line should contain `YES' if the figure is left-right symmetric. and `NO', otherwise.
The following shows sample input and output for three test cases.
Sample Input
3 5 -2 5 0 0 6 5 4 0 2 3 4 2 3 0 4 4 0 0 0 4 5 14 6 10 5 10 6 14
Sample Output
YES NO YES
分析:
此题判断平面上的点是否左右对称分布,也即是否存在竖直对称轴。
对称轴(假设存在)可由点的横坐标和求出。因为担心精度问题,我并未将line直接求出,而是算倍数关系。
可先对点的数目的奇偶性进行分析,若是奇数,则要想对称分布,中间的点必须在对称轴上,否则不对称。
对于偶数个点,可先对点排序。排序后从两端开始取点,若能取出关于对称轴对称分布的点对,则继续取点,否则停止。
代码:
(还是有些乱的,要休息一下了。。。)
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1010;
typedef struct {
double x, y;
} dot;
dot pos[maxn];
double loc_x[maxn];
int n;
bool cmp(dot a, dot b) {
return a.x < b.x || (a.x == b.x) && (a.y < b.y);
}
void disp() {
for (int i = 0; i < n; i++)
cout << pos[i].x << "," << pos[i].y << "\n";
}
int main() {
int t;
cin >> t;
while (t--) {
double line = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> pos[i].x >> pos[i].y;
loc_x[i] = pos[i].x;
line += pos[i].x;
}
sort(pos, pos + n, cmp);
// disp();
for (int i = 0; i < n; i++) loc_x[i] = n * pos[i].x;
if (n % 2 == 1 && pos[n / 2].x * n == line) {
cout << "YES\n";
continue;
}
int flag = 0;
for (int i = 0; i < n / 2; i++) {
if (pos[i].x * n == line)
continue;
for (int j = n - 1; j >= n / 2; j--)
if ((pos[i].x + pos[j].x) * n == 2 * line) {
if (pos[i].y != pos[j].y) {
flag = 1;
}
else {
flag = 0;
break;
}
}
else
flag = 1;
}
if (!flag)
cout << "YES\n";
else
cout << "NO\n";
}
return 0;
}
870

被折叠的 条评论
为什么被折叠?



