首页 > 代码库 > poj2194Stacking Cylinders

poj2194Stacking Cylinders

链接

可以根据反余弦和反正切算出角a和b的值, 然后向量旋转就可以了,图中的状态旋转rotate((2,0),a+b)  反状态把角度反过来,点取(-2,0)即可。

不知道是不是理解错了,题意写着两圆距离》2,《3.4,在求得时候就加了特判,一直WA。。。去了特判就过了。

为了提高精度,可以全化为atan2.

  1 #include <iostream>  2 #include<cstdio>  3 #include<cstring>  4 #include<algorithm>  5 #include<stdlib.h>  6 #include<vector>  7 #include<cmath>  8 #include<queue>  9 #include<set> 10 using namespace std; 11 #define N 100000 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-10; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 const double r = 1.0; 18 const double rd = 3.40; 19 struct point 20 { 21     double x,y,r; 22     point(double x=0,double y=0):x(x),y(y){} 23 }p[N],q[N]; 24 typedef point pointt; 25 pointt operator -(point a,point b) 26 { 27     return point(a.x-b.x,a.y-b.y); 28 } 29 double dis(point a) 30 { 31     return sqrt(a.x*a.x+a.y*a.y); 32 } 33 double dot(point a,point b) 34 { 35     return a.x*b.x+a.y*b.y; 36 } 37 double angle(point a,point b) 38 { 39     return acos(dot(a,b)/dis(a)/dis(b)); 40 } 41 double angle1(point v) 42 { 43     return atan2(v.y,v.x); 44 } 45 int dcmp(double x) 46 { 47     if(fabs(x)<eps) return 0; 48     return x<0?-1:1; 49 } 50 point rotate(point a,double rad)//逆时针旋转 51 { 52     return point(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad)); 53 } 54 bool cmp(point a,point b) 55 { 56     return a.x<b.x; 57 } 58 int main() 59 { 60     int n,i,j; 61     while(scanf("%d",&n)&&n) 62     { 63         for(i = 1; i <= n;i++) 64         { 65             double x; 66             scanf("%lf",&x); 67             p[i] = point(x,1); 68         } 69         sort(p+1,p+n+1,cmp); 70         int tn = n; 71         double maxz = 0; 72         point tp; 73         while(1) 74         { 75             int g = 0; 76             for(i = 1; i < tn; i++) 77             { 78                 if(maxz<p[i].y) 79                 { 80                     maxz = p[i].y; 81                     tp = p[i]; 82                 } 83                // if(dcmp(dis(p[i]-p[i+1])-2*r)<0) continue; 84                // if(dcmp(dis(p[i]-p[i+1])-rd)>0) continue; 85  86                 double b = atan2(fabs(p[i].y-p[i+1].y),fabs(p[i].x-p[i+1].x)); 87                 double d = dis(p[i]-p[i+1])/2; 88                 double dd = sqrt(4-(d*d)); 89                 double a = atan2(dd,d); 90                 if(dcmp(a+b-pi/2.0)>0) continue; 91                 if(p[i].y<p[i+1].y) 92                 { 93                     point pp = point(2.0,0); 94                     q[++g] = rotate(pp,a+b); 95                     q[g] = point(q[g].x+p[i].x,q[g].y+p[i].y); 96                 } 97                 else 98                 { 99                     point pp = point(-2,0);100                     q[++g] = rotate(pp,-a-b);101                     q[g] = point(q[g].x+p[i+1].x,q[g].y+p[i+1].y);102                 }103             }104             if(maxz<p[tn].y)105             {106                 maxz  = p[tn].y;107                 tp = p[tn];108             }109             if(!g) break;110             tn = g;111             for(i = 1; i <= g ; i++)112             p[i] = q[i];113         }114         printf("%.4f %.4f\n",tp.x,tp.y);115     }116     return 0;117 }
View Code