pku 2526(Center of symmetry)

 1 /*
 2 *  判断一堆点组成的形状是否为对称的 
 3 */
 4 
 5 #include <cmath>
 6 #include <cstdio>
 7 #include <cstdlib>
 8 #include <iostream>
 9 
10 using namespace std;
11 
12 const int N = 10005;
13 const double EPS = 1e-8;
14 
15 struct point {
16     double x, y;
17 }p[N], s;
18 int used[N];
19 
20 int Rlcmp(double r1, double r2 = 0) {
21     if (fabs(r1 - r2) < EPS) return 0;
22     return r1 > r2 ? 1 : -1;
23 }
24 
25 int cmp(const void *a, const void *b) {//按横坐标从小到大排序,横坐标相等时,按纵坐标从小到大排序 
26     point *c = (point *)a;
27     point *d = (point *)b;
28 //    if (c->x == d->x) return (int)(c->y - d->y);
29 //    return (int)(c->x - d->x);
30     if (fabs(c->x - d->x) < EPS) return c->y > d->y ? 1 : -1;
31     return c->x > d->x ? 1 : -1;
32 }
33 
34 bool solve(int n) {
35     int i;
36     s.x = s.y = 0;
37     for (i=0; i<n; ++i) {
38         used[i] = 1;
39         s.x += p[i].x, s.y += p[i].y;
40     }
41     s.x /= n, s.y /= n;    //对称中心 
42     for (i=0; i<n; ++i) {  //将坐标系平移到点s 
43         p[i].x -= s.x, p[i].y -= s.y;
44         if (Rlcmp(p[i].x) == 0 && Rlcmp(p[i].y) == 0) used[i] = 0;//判断跟点s重合的点,去掉 
45     }
46     qsort(p, n, sizeof(point), cmp);
47     for (i=0; i<n; ++i) {//二分查找是否存在一个点,符合p-s = s-q 
48         if (used[i]) {
49             used[i] = 0;
50             int ok = 0; //标志,初始为不存在 
51             int left = 0;
52             int right = n - 1;
53             while (left <= right) {
54                 int mid = (left + right) >> 1;
55                 int u = Rlcmp(p[i].x + p[mid].x);
56                 if (u == -1) left = mid + 1;
57                 else if (u == 0) {
58                     int v = Rlcmp(p[i].y + p[mid].y);
59                     if (v == -1) left = mid + 1;
60                     else if (v == 0) {
61                         ok = 1; //存在 
62                         used[mid] = 0;
63                         break;
64                     }
65                     else right = mid - 1; 
66                 }
67                 else right = mid - 1;
68             }
69             if (ok == 0) break;//不存在 
70         }
71     }
72     if (i == n) return true;
73     return false;
74 }
75 
76 int main() {
77     int t;
78     scanf ("%d", &t);
79     while (t--) {
80         int n;
81         scanf ("%d", &n);
82         for (int i=0; i<n; ++i) scanf ("%lf%lf", &p[i].x, &p[i].y);
83         bool yes = solve(n);
84         if (yes) printf ("yes\n");
85         else printf ("no\n");
86     }
87     return 0;
88 }

 

posted on 2012-06-03 08:59  Try86  阅读(211)  评论(0编辑  收藏  举报