Gym 100942A Three seamarks

题目链接: http://codeforces.com/problemset/gymProblem/100942/A

------------------------------------------------------------------------------------

我们可以把给定的角看成圆周角 从而算出圆心角

然后每条边以及一个角可以确定两个可能的圆

 

如果$M1\ M2$确定出来的两个圆与$M2\ M3$确定出来的两个圆圆心不同的话

再判断这两个圆的交点即为答案 另外每次两个交点中一定有一个点是$M2$

 

如果圆心相同就是四点共圆了

 

此题卡精度比较严重 不要随意地使用三角函数库函数 尤其是$atan2$这类的

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <algorithm>
  5 using namespace std;
  6 const double eps = 1e-6, inf = 1e8, pi = acos(-1.0);
  7 const double eps2 = 1e-2;
  8 struct point
  9 {
 10     double x, y;
 11     point(){}
 12     point(double _x,double _y)
 13     {
 14         x = _x;
 15         y = _y;
 16     }
 17     point operator - (const point &p) const
 18     {
 19         return point(x - p.x, y - p.y);
 20     }
 21     point operator + (const point &p) const
 22     {
 23         return point(x + p.x, y + p.y);
 24     }
 25     double operator * (const point &p) const
 26     {
 27         return x * p.y - y * p.x;
 28     }
 29     double operator / (const point &p) const
 30     {
 31         return x * p.x + y * p.y;
 32     }
 33 }a[3];
 34 struct circle
 35 {
 36     double x, y, r;
 37 }c[4];
 38 int t, cnt;
 39 double ang1, ang2;
 40 bool flag;
 41 double getdist2(const point &aa)
 42 {
 43     return (aa.x * aa.x + aa.y * aa.y);
 44 }
 45 double mycos(double B, double C, double A)
 46 {
 47     return (B * B + C * C - A * A) / (B * C * 2);
 48 }
 49 double mycos2(const point &aa, const point &bb, const point &cc)
 50 {
 51     double C2 = getdist2(aa - bb), A2 = getdist2(bb - cc), B2 = getdist2(cc - aa);
 52     return (B2 + C2 - A2) / (sqrt(B2 * C2) * 2);
 53 }
 54 point rotate(const point &p, double cost, double sint)
 55 {
 56     double x = p.x, y = p.y;
 57     return point(x * cost - y * sint, x * sint + y * cost);
 58 }
 59 void getcircle(const point &aa, const point &bb, double ang)
 60 {
 61     ang = (ang < pi * 0.5 ? ang: pi - ang);
 62     point mid;
 63     mid.x = (aa.x + bb.x) * 0.5;
 64     mid.y = (aa.y + bb.y) * 0.5;
 65     if(ang + eps < pi * 0.5)
 66     {
 67         double tan1 = tan(ang);
 68         c[cnt].x = mid.x + (aa.y - mid.y) / tan1;
 69         c[cnt].y = mid.y - (aa.x - mid.x) / tan1;
 70         c[cnt].r = sqrt(getdist2(mid - point(c[cnt].x, c[cnt].y)) + 
 71         getdist2(mid - aa));
 72         ++cnt;
 73         c[cnt].x = mid.x - (aa.y - mid.y) / tan1;
 74         c[cnt].y = mid.y + (aa.x - mid.x) / tan1;
 75         c[cnt].r = c[cnt - 1].r;
 76         ++cnt;
 77     }
 78     else
 79     {
 80         c[cnt].x = mid.x;
 81         c[cnt].y = mid.y;
 82         c[cnt].r = sqrt(getdist2(mid - aa));
 83         ++cnt;
 84         c[cnt] = c[cnt - 1];
 85         ++cnt;
 86     }
 87 }
 88 bool checkpoint(const point &re)
 89 {
 90     for(int i = 0; i < 3; ++i)
 91         if(getdist2(a[i] -re) < eps)
 92             return 0;
 93     double tmp = acos(mycos2(re, a[0], a[1])) - ang1 - pi;
 94     while(tmp < -eps2)
 95         tmp += pi;
 96     if(abs(tmp) > eps2)
 97         return 0;
 98     tmp = acos(mycos2(re, a[1], a[2])) - ang2 - pi;
 99     while(tmp < -eps2)
100         tmp += pi;
101     return abs(tmp) < eps2;
102 }
103 void getpoint2(const circle &c1)
104 {
105     double dab = sqrt(getdist2(point(a[0].x - a[1].x, a[0].y - a[1].y)));
106     double ang = acos(dab / (c1.r * 2));
107     ang -= ang1;
108     double len = c1.r * 2 * cos(ang);
109     double cang1 = cos(ang1);
110     double l2 = len * cang1;
111     point d, re;
112     d.x = a[1].x + (a[0].x - a[1].x) * l2 / dab;
113     d.y = a[1].y + (a[0].y - a[1].y) * l2 / dab;
114     double l3 = len * sqrt(1 - cang1 * cang1);
115     re.x = d.x + (a[0].y - a[1].y) * l3 / dab;
116     re.y = d.y - (a[0].x - a[1].x) * l3 / dab;
117     if(checkpoint(re))
118     {
119         printf("%.8f %.8f\n", re.x, re.y);
120         flag = 1;
121         return;
122     }
123     re.x = d.x - (a[0].y - a[1].y) * l3 / dab;
124     re.y = d.y + (a[0].x - a[1].x) * l3 / dab;
125     if(checkpoint(re))
126     {
127         printf("%.8f %.8f\n", re.x, re.y);
128         flag = 1;
129         return;
130     }
131 }
132 void getpoint(circle c1, circle c2)
133 {
134     double dab = sqrt(getdist2(point(c1.x, c1.y) - point(c2.x, c2.y)));
135     if(dab < eps)
136     {
137         getpoint2(c1);
138         return;
139     }
140     if(c1.r > c2.r)
141         swap(c1, c2);
142     double cost = mycos(c1.r, dab, c2.r);
143     double sint = sqrt(1 - cost * cost);
144     point re = rotate(point(c2.x, c2.y) - point(c1.x, c1.y), cost, sint);
145     re.x = c1.x + re.x * (c1.r / dab);
146     re.y = c1.y + re.y * (c1.r / dab);
147     if(getdist2(a[1] - re) < eps)
148     {
149         re = rotate(point(c2.x, c2.y) - point(c1.x, c1.y), cost, -sint);
150         re.x = c1.x + re.x * (c1.r / dab);
151         re.y = c1.y + re.y * (c1.r / dab);
152     }
153     if(!checkpoint(re))
154         return;
155     flag = 1;
156     printf("%.8f %.8f\n", re.x, re.y);
157 }
158 int main()
159 {
160     scanf("%d", &t);
161     while(t--)
162     {
163         for(int i = 0; i < 3; ++i)
164             scanf("%lf%lf", &a[i].x, &a[i].y);
165         scanf("%lf%lf", &ang1, &ang2);
166         ang1 = ang1 * pi / 180;
167         ang2 = ang2 * pi / 180;
168         cnt = 0;
169         getcircle(a[0], a[1], ang1);
170         getcircle(a[1], a[2], ang2);
171         flag = 0;
172             getpoint(c[0], c[2]);
173         if(!flag)
174             getpoint(c[0], c[3]);
175         if(!flag)
176             getpoint(c[1], c[2]);
177         if(!flag)
178             getpoint(c[1], c[3]);
179     }
180     return 0;
181 }

 

posted @ 2016-04-03 22:09 sagitta 阅读(...) 评论(...) 编辑 收藏