BZOJ2592: [Usaco2012 Feb]Symmetry

特别选出其中两个点,比如p[0]和p[1],两个点要么在对称轴上,要么一个在对称轴上,要么是对称点,要么分别和其他点对称而共享一个对称轴。

这样枚举其他点和这两点构成对称轴,可以枚举出2n个对称轴,复杂度是O(n),中间判断一下是否其中一个点在对称轴上。

对于枚举得到的O(n)个对称轴,用set或hash的方法存点,就可以通过计算对称点是否存在的方法O(nlogn)或O(n)来判断是否是对称轴了。

没想到36ms,set还挺快。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<math.h>
 5 #include<algorithm>
 6 #include<set>
 7 using namespace std;
 8 const int maxn = 1111;
 9 const double eps = 1e-8;
10 const double pi = acos(-1.0);
11 int dcmp(double x) {return (x > eps) - (x < -eps);}
12 inline double Sqr(double x) {return x * x;}
13 /**************************************************/
14 struct Point
15 {
16     double x, y;
17     Point(){x = y = 0;}
18     Point(double a, double b)
19     {x = a, y = b;}
20     inline Point operator-(const Point &b)const
21     {return Point(x - b.x, y - b.y);}
22     inline Point operator+(const Point &b)const
23     {return Point(x + b.x, y + b.y);}
24     inline Point operator*(const double &b)const
25     {return Point(x * b, y * b);}
26     inline double dot(const Point &b)const
27     {return x * b.x + y * b.y;}
28     inline double cross(const Point &b, const Point &c)const
29     {return (b.x - x) * (c.y - y) - (c.x - x) * (b.y - y);}
30     inline bool operator<(const Point &b)const
31     {return dcmp(x - b.x) ? x < b.x : y < b.y;}
32     inline bool operator==(const Point &b)const
33     {return !dcmp(x - b.x) && !dcmp(y - b.y);}
34 };
35 int n;
36 Point p[maxn], mps, mpe;
37 set<Point> s;
38 Point LineCross(const Point &a, const Point &b, const Point &c, const Point &d)
39 {
40     double u = a.cross(b, c), v = b.cross(a, d);
41     return Point((c.x * v + d.x * u) / (u + v), (c.y * v + d.y * u) / (u + v));
42 }
43 Point AntiPoint(const Point &p, const Point &a, const Point &b)
44 {
45     if(a == b) return Point(a.x + a.x - p.x, a.y + a.y - p.y);
46     Point tmp(p.x + a.y - b.y, p.y + b.x - a.x);
47     return LineCross(p, tmp, a, b) * 2 - p;
48 }
49 bool Judge(Point a, Point b)
50 {
51     for(int i = 0; i < n; ++ i)
52         if(!s.count(AntiPoint(p[i], a, b))) return false;
53     return true;
54 }
55 bool MakeMP(Point a, Point b, Point &c, Point &d)
56 {
57     if(a == b) return false;
58     c = (a + b) * 0.5;
59     d = Point(c.x + a.y - b.y, c.y + b.x - a.x);
60     return true;
61 }
62 
63 int main()
64 {
65     int i, ans;
66     while(scanf("%d", &n) != EOF)
67     {
68         s.clear();
69         for(i = 0; i < n; ++ i) scanf("%lf%lf", &p[i].x, &p[i].y), s.insert(p[i]);
70         ans = Judge(p[0], p[1]);
71         MakeMP(p[0], p[1], mps, mpe);
72         ans += Judge(mps, mpe);
73         for(i = 2; i < n; ++ i)
74         {
75             MakeMP(p[0], p[i], mps, mpe);
76             ans += Judge(mps, mpe);
77             MakeMP(p[1], p[i], mps, mpe);
78             ans += Judge(mps, mpe) && !dcmp(p[0].cross(mps, mpe));
79         }
80         printf("%d\n", ans);
81     }
82     return 0;
83 }
posted @ 2012-10-11 16:01  CSGrandeur  阅读(520)  评论(0编辑  收藏  举报