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 }

 

依旧在写水题。。。

 

你可能感兴趣的:(poj)