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 }