# HDU 6631 line symmetric 计算几何

AC代码

#include <bits/stdc++.h>
#define SIZE 1007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
int t, n;
struct Point {
double x, y;
}p[SIZE], a, b, tp, mid, mx, mid2, nullp;
void io() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
double cross(Point a, Point b, Point c) { return (b.x - a.x) * (c.y - b.y) - (b.y - a.y) * (c.x - b.x); }
double cdot(Point a, Point b, Point c) { return (b.x - a.x) * (b.x - c.x) + (b.y - c.y) * (b.y - a.y); }
int spjudge(int j, int k, Point mid, Point mid2) {
bool f1 = false, f2 = false; int num = 0;
if (cross(mid, p[j], mid2)) {
int pre = j - 1, post = j + 1;
if (pre < 1) pre += n;
if (post > n) post -= n;
if (cross(mid, p[pre], mid2)*cross(mid, p[post], mid2) < 0) f1 = true;
if (cross(mid, p[pre], mid2)*cross(mid, p[j], mid2) < 0) f1 = true;
if (cross(mid, p[post], mid2)*cross(mid, p[j], mid2) < 0) f1 = true;
}
else f1 = true;
if (cross(mid, p[k], mid2)) {
int pre = k + 1, post = k - 1;
if (pre < 1) pre += n;
if (post > n) post -= n;
if (cross(mid, p[pre], mid2)*cross(mid, p[post], mid2) < 0) f2 = true;
if (cross(mid, p[pre], mid2)*cross(mid, p[j], mid2) < 0) f2 = true;
if (cross(mid, p[post], mid2)*cross(mid, p[j], mid2) < 0) f2 = true;
}
else f2 = true;
if (f1&&f2) return 1;
else return 0;
}
bool judge1() {
rep(i, 1, n) {
int num = 0;
a = p[i]; b = p[i % n + 1];
mid.x = (a.x + b.x) / 2; mid.y = (a.y + b.y) / 2;
mid2.x = mid.x + (a.y - mid.y); mid2.y = mid.y + (mid.x - a.x);
int tt = n / 2 - 1;
if (n % 2) {
tp = p[(i + n / 2) % n + 1];
if (cross(mid, tp, mid2)) ++num;
}
int j = i - 1, k = i + 2;
while (tt--) {
if (j < 1) j += n;
if (k > n) k -= n;
mx.x = (p[j].x + p[k].x) / 2;
mx.y = (p[j].y + p[k].y) / 2;
if ((cdot(p[i], mid, mx) != 0) || (cdot(mid, mx, p[j]) != 0)) {
++num;
num += spjudge(j, k, mid, mid2);
}
--j, ++k;
}
if (num <= 1) return true;
}
return false;
}
bool judge2() {
rep(i, 1, n) {
int num = 0;
a = p[i]; b = p[(i + 1) % n + 1];
mid.x = (a.x + b.x) / 2; mid.y = (a.y + b.y) / 2;
mid2.x = mid.x + (a.y - mid.y); mid2.y = mid.y + (mid.x - a.x);
int tt = n / 2 - 1;
tp = p[i % n + 1];
if (cross(mid, tp, mid2)) ++num;
if (n % 2 == 0) {
tp = p[(i + n / 2) % n + 1];
if (cross(mid, tp, mid2)) ++num;
}
int j = i - 1, k = i + 3;
while (tt--) {
if (j < 1) j += n;
if (k > n) k -= n;
mx.x = (p[j].x + p[k].x) / 2;
mx.y = (p[j].y + p[k].y) / 2;
if ((cdot(p[i], mid, mx) != 0) || (cdot(mid, mx, p[j]) != 0)) {
++num;
num += spjudge(j, k, mid, mid2);
}
--j, ++k;
}
if (num <= 1) return true;
}
return false;
}
int main() {
io(); cin >> t;
while (t--) {
cin >> n;
rep(i, 0, 1000) p[i] = nullp;
rep(i, 1, n) cin >> p[i].x >> p[i].y;
if (n < 5) { cout << "Y\n"; continue; }
if (judge1()) cout << "Y\n";
else if (judge2()) cout << "Y\n";
else cout << "N\n";
}
}

posted @ 2019-08-06 15:33  st1vdy  阅读(647)  评论(3编辑  收藏  举报