poj crane

来源:互联网 发布:linux权限命令 编辑:程序博客网 时间:2024/05/05 12:12
  1 #include<stdio.h>  2 #include<math.h>  3 #include<string.h>  4 #include<stdlib.h>  5 #define N (10010<<2)  6 #define maxn 10000  7 #define lson l,m,rt<<1  8 #define rson m+1,r,rt<<1|1  9 #define pi acos(-1.0) 10  11 int ang[N]; 12 double x[N],y[N],len[maxn+1]; 13  14 void Rotate(int rt,double rad) 15 { 16     double s=x[rt],t=y[rt]; 17     x[rt]=s*cos(rad)-t*sin(rad); 18     y[rt]=s*sin(rad)+t*cos(rad); 19 } 20  21 double getrad(double x) 22 { 23     return x*pi/180.0; 24 } 25  26 void PushDown(int rt) 27 { 28     if(ang[rt]) 29     { 30         ang[rt<<1]+=ang[rt]; 31         ang[rt<<1|1]+=ang[rt]; 32         double rad=getrad(ang[rt]); 33         ang[rt]=0; 34         Rotate(rt<<1,rad); 35         Rotate(rt<<1|1,rad); 36     } 37 } 38  39 void PushUp(int rt) 40 { 41     x[rt]=x[rt<<1]+x[rt<<1|1]; 42     y[rt]=y[rt<<1]+y[rt<<1|1]; 43 } 44  45 void build(int l,int r,int rt) 46 { 47     ang[rt]=0; 48     if(l==r) 49     { 50         x[rt]=0; 51         y[rt]=len[l]; 52         return ; 53     } 54     int m=(l+r)>>1; 55     build(lson); 56     build(rson); 57     PushUp(rt); 58 } 59  60 void update(int p,int del,int l,int r,int rt) 61 { 62     if(l==r) 63     { 64         double rad=getrad(del); 65         Rotate(rt,rad); 66         return; 67     } 68     int m=(l+r)>>1; 69     PushDown(rt); 70     if(p<=m) 71     { 72         double rad=getrad(del); 73         update(p,del,lson); 74         Rotate(rt<<1|1,rad); 75         ang[rt<<1|1]+=del; 76     } 77     else 78         update(p,del,rson); 79     PushUp(rt); 80 } 81  82 int main(void) 83 { 84     int n,q; 85     int flag=0; 86     int index,degree[maxn+1],d; 87     while(~scanf("%d%d",&n,&q)) 88     { 89         memset(degree,0,sizeof(degree)); 90         memset(ang,0,sizeof(ang));/*旋转角度初始化为0,也就是一开始不旋转,这一步也可以放在build函数里面进行,不能遗漏*/ 91         if(flag) puts(""); 92         else flag=1; 93         for(int i=1; i<=n; i++) 94             scanf("%lf",len+i); 95         build(1,n,1); 96         while(q--) 97         { 98           scanf("%d%d",&index,&d); 99           d-=180;100           index++;/*index要先增加,然后再和degree[intdex]求旋转角度*/101           int delta=d-degree[index];102           degree[index]=d;103           update(index,delta,1,n,1);104           printf("%.2f %.2f\n",x[1],y[1]);105         }106     }107     return 0;108 }

 关于Rotae函数是这样理解的,更新时表示index+1段之后的线段绕index段末端点旋转delta度,x,y分别对应index+1之后的线段在x轴,y轴上投影。
根据x'=x*cos(rad)-y*sin(rad),y'=x*sin(rad)+y*cos(rad)可以将旋转后的投影算出来。

0 0