您的位置:首页 > 其它

pku 2526(Center of symmetry)

2012-06-03 08:59 323 查看
/*
*  判断一堆点组成的形状是否为对称的
*/

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

const int N = 10005;
const double EPS = 1e-8;

struct point {
double x, y;
}p
, s;
int used
;

int Rlcmp(double r1, double r2 = 0) {
if (fabs(r1 - r2) < EPS) return 0;
return r1 > r2 ? 1 : -1;
}

int cmp(const void *a, const void *b) {//按横坐标从小到大排序,横坐标相等时,按纵坐标从小到大排序
point *c = (point *)a;
point *d = (point *)b;
//    if (c->x == d->x) return (int)(c->y - d->y);
//    return (int)(c->x - d->x);
if (fabs(c->x - d->x) < EPS) return c->y > d->y ? 1 : -1;
return c->x > d->x ? 1 : -1;
}

bool solve(int n) {
int i;
s.x = s.y = 0;
for (i=0; i<n; ++i) {
used[i] = 1;
s.x += p[i].x, s.y += p[i].y;
}
s.x /= n, s.y /= n;    //对称中心
for (i=0; i<n; ++i) {  //将坐标系平移到点s
p[i].x -= s.x, p[i].y -= s.y;
if (Rlcmp(p[i].x) == 0 && Rlcmp(p[i].y) == 0) used[i] = 0;//判断跟点s重合的点,去掉
}
qsort(p, n, sizeof(point), cmp);
for (i=0; i<n; ++i) {//二分查找是否存在一个点,符合p-s = s-q
if (used[i]) {
used[i] = 0;
int ok = 0; //标志,初始为不存在
int left = 0;
int right = n - 1;
while (left <= right) {
int mid = (left + right) >> 1;
int u = Rlcmp(p[i].x + p[mid].x);
if (u == -1) left = mid + 1;
else if (u == 0) {
int v = Rlcmp(p[i].y + p[mid].y);
if (v == -1) left = mid + 1;
else if (v == 0) {
ok = 1; //存在
used[mid] = 0;
break;
}
else right = mid - 1;
}
else right = mid - 1;
}
if (ok == 0) break;//不存在
}
}
if (i == n) return true;
return false;
}

int main() {
int t;
scanf ("%d", &t);
while (t--) {
int n;
scanf ("%d", &n);
for (int i=0; i<n; ++i) scanf ("%lf%lf", &p[i].x, &p[i].y);
bool yes = solve(n);
if (yes) printf ("yes\n");
else printf ("no\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: