POJ 2194/POJ 2850

题意:

一堆圆,R=1,已知底层各个的圆心坐标,求最上面一个圆心的坐标。

题解:

模拟,尽量少使用反三角函数,不得不用时,尽量用atan2即可。

View Code
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <cmath>
 7 
 8 #define N 222
 9 
10 using namespace std;
11 
12 struct PO
13 {
14     double x,y;
15 }p[N][N];
16 
17 int n;
18 
19 inline bool cmp(const PO &a,const PO &b)
20 {
21     return a.x<b.x;
22 }
23 
24 inline void read()
25 {
26     for(int i=1;i<=n;i++)
27     {
28         scanf("%lf",&p[1][i].x);
29         p[1][i].y=1.0;
30     }
31     sort(p[1]+1,p[1]+1+n,cmp);
32 }
33 
34 inline PO rotate(PO a,double hd)
35 {
36     PO c;
37     c.x=a.x*cos(hd)-a.y*sin(hd);
38     c.y=a.x*sin(hd)+a.y*cos(hd);
39     return c;
40 }
41 
42 inline double getlen(PO &a)//向量的模 
43 {
44     return sqrt(a.x*a.x+a.y*a.y);
45 }
46 
47 inline double getdis2(PO &a,PO &b)
48 {
49     return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
50 }
51 
52 inline void go()
53 {
54     int c=1;
55     while(n>1)
56     {
57         c++;
58         for(int i=1;i<n;i++)
59         {
60             double af=atan2(sqrt(4.0-getdis2(p[c-1][i],p[c-1][i+1])*0.25),sqrt(getdis2(p[c-1][i],p[c-1][i+1]))*0.5);
61             //atan2精度较高,其他的反三角函数精度都比较差。。。 
62             PO s;
63             s.y=p[c-1][i+1].y-p[c-1][i].y;
64             s.x=p[c-1][i+1].x-p[c-1][i].x;
65             double k=2.0/getlen(s);
66             s.y*=k; s.x*=k;
67             
68             s=rotate(s,af);
69             p[c][i].y=p[c-1][i].y+s.y;
70             p[c][i].x=p[c-1][i].x+s.x;
71         }
72         n--;
73     }
74     printf("%.4lf %.4lf\n",p[c][1].x,p[c][1].y);
75 }
76 
77 int main()
78 {
79     while(scanf("%d",&n),n) read(),go();
80     return 0;
81 }

依旧在写水题。。。

原文地址:https://www.cnblogs.com/proverbs/p/2927308.html