HDU 6242 Geometry Problem (Computational Geometry randomization +)

Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=6242

Idea: When n == take any point p 1 as the center can be.

    n> = 2 && n <5 At this time there may be all collinear points, so as to take the center of the mid point between two arbitrary circle.

    n> = 5 guarantees the solvability. It is impossible to have a little collinear case, the probability of randomly selected three points on the positive solution of the circle is 1/8, is still quite large ....

    Outside the school to write an algorithm of random seed time .... time (0) To force turn into int, or will WA, why not make ....

AC Code:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const double eps = 1e-4;
  4 const double INF = 1e18;
  5 const int maxn = 1e5 + 5;
  6 int sgn(double x)
  7 {
  8     if(fabs(x) < eps) return 0;
  9     else return x < 0 ? -1 : 1;
 10 }
 11 struct Point{
 12     double x, y;
 13     Point(){}
 14     Point(double _x, double _y){
 15         x = _x; y = _y;
 16     }
 17     void input()
 18     {
 19         scanf("%lf %lf", &x, &y);
 20     }
 21     bool operator ==(const Point &b) const{
 22         return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
 23     }
 24     bool operator <(const Point &b) const{
 25         return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
 26     }
 27     Point operator -(const Point &b) const{
 28         return Point(x - b.x, y - b.y);
 29     }
 30     Point operator +(const Point &b) const{
 31         return Point(x + b.x, y + b.y);
 32     }
 33     double operator ^(const Point &b) const{
 34         return x*b.y - b.x*y;
 35     }
 36     double operator *(const Point &b) const{
 37         return x*b.x + y*b.y;
 38     }
 39     Point operator*(const double &k)const{
 40         return Point(x*k,y*k);
 41     }
 42     Point operator/(const double &k)const{
 43         return Point(x/k,y/k);
 44     }
 45     Point rotleft(){
 46         return Point(-y, x);
 47     }
 48     double distance(Point p)
 49     {
 50         return hypot(x - p.x,y - p.y);
 51     }
 52 } p[maxn];
 53 struct Line{
 54     Point s, e;
 55     Line(){}
 56     Line(Point _s, Point _e){
 57         s = _s, e = _e;
 58     }
 59     Point crosspoint(Line v){
 60         double a1 = (v.e - v.s) ^ (s - v.s);
 61         double a2 = (v.e - v.s) ^ (e - v.s);
 62         return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
 63     }
 64 };
 65 struct circle{
 66     Point p;
 67     double r;
 68     circle(){}
 69     circle(Point a, Point b, Point c){
 70         Line u = Line( (a + b) / 2, ( (a + b) / 2) + ( (b - a).rotleft() ));
 71         Line v = Line( (b + c) / 2, ( (b + c) / 2) + ( (c - b).rotleft() ));
 72         p = u.crosspoint(v);
 73         r = p.distance(a);
 74     }
 75     int relation(Point b){
 76         double dst = b.distance(p);
 77         if(sgn(dst - r)<0) return 2;
 78         else if(sgn(dst - r) == 0) return 1;
 79         return 0;
 80     }
 81 };
 82 int main()
 83 {
 84     int t;
 85     scanf("%d",&t);
 86     srand((int)time(0));
 87     while(t--)
 88     {
 89         int n;
 90         scanf("%d",&n);
 91         for(int i = 0;i < n;i++) p[i].input();
 92         if(n == 1) printf("0.000 0.000 %.6f\n",p[0].distance(Point(0,0)));
 93         else if(n >= 2 && n < 5){
 94             Point v = (p[0] + p[1])/2;
 95             printf("%.6f %.6f %.6f\n", v.x, v.y, 0.5*p[0].distance(p[1]));
 96         }
 97         else{
 98             while(1){
 99                 int a = rand() % n, b = a, c = a;
100                 while(b = rand() % n){
101                     if(b != a) break;
102                 }
103                 while(c = rand() % n){
104                     if(c != a && c != b) break;
105                 }
106                 circle C = circle(p[a], p[b], p[c]);
107                 int num = 0;
108                 for(int i = 0;i < n;i++)
109                 {
110                     if(C.relation(p[i]) == 1) num++;
111                 }
112                 if(num >= (n + 1) / 2){
113                     printf("%.6f %.6f %.6f\n",C.p.x ,C.p.y, C.r);
114                     break;
115                 }
116             }
117         }
118     }
119     return 0;
120 }

 

Guess you like

Origin www.cnblogs.com/Carered/p/11568666.html