对应POJ题目:点击打开链接
Time Limit: 2000MS | Memory Limit: 65536KB | 64bit IO Format: %I64d & %I64u |
Description
Input
Output
Sample Input
2 1 10 5 1 90 3 2 5 5 5 1 270 2 90
Sample Output
5.00 10.00 -10.00 5.00 -5.00 10.00
Source
题意:有一个吊车由很多个不同长度的线段组成,一开始是一条长直线起点在(0,0),尾节点在(0,sum[n]),每条线段之间的夹角的初始值是180度。然后有一些操作a、 b将第a条线段和a+1之间的夹角变成b度,经过每一次操作都要求出尾节点的坐标。
思路:线段树区间更新;结点值保存该区间的向量及旋转角(注意他给出的不是旋转角)一个区间的向量值=左子区间的向量+右子区间的向量。
求一个向量(x0,y0)逆时针旋转B度后的向量有一个公式:
x1= x0 * cosB - y0 * sinB
y1 = x0 * sinB + y0 * cosB
顺时针就把-B代入:
x1= x0 * cosB + y0 * sinB
y1 = -x0 * sinB + y0 * cosB
还有一点很恶心,就是旋转角的计算;用一个angle[i]数组表示第i段线段跟第i-1段线段的夹角,我这里是计顺时针旋转的,我初始化angle[]为180,故每次更新时,旋转角t=angle[i]-b; angle[i]=b;
#include<cstdio> #include<cstdlib> #include<cmath> #include<map> #include<queue> #include<stack> #include<vector> #include<algorithm> #include<cstring> #include<string> #include<iostream> #define ms(x,y) memset(x,y,sizeof(x)) #define eps 1e-6 const int MAXN=10000+10; const int INF=1<<30; using namespace std; double px[MAXN<<2]; double py[MAXN<<2]; int turn[MAXN<<2]; int angle[MAXN];//第i个线段与第i-1个线段的夹角 //const double pi = acos(-1.0); const double pi = 3.141592653; void down(int rt) { if(turn[rt]){ int t=turn[rt]; turn[rt<<1]+=t; turn[rt<<1|1]+=t; //左向量旋转t度 double x=px[rt<<1], y=py[rt<<1]; px[rt<<1]=x*cos(t*pi/180) + y*sin(t*pi/180); py[rt<<1]=-x*sin(t*pi/180) + y*cos(t*pi/180); //右向量旋转t度 x=px[rt<<1|1], y=py[rt<<1|1]; px[rt<<1|1]=x*cos(t*pi/180) + y*sin(t*pi/180); py[rt<<1|1]=-x*sin(t*pi/180) + y*cos(t*pi/180); turn[rt]=0; } } void buildline(int rt, int left, int right) { if(left==right){ px[rt]=0.0; scanf("%lf", &py[rt]); return; } int mid=(left+right)>>1; buildline(rt<<1, left, mid); buildline(rt<<1|1, mid+1, right); px[rt]=px[rt<<1] + px[rt<<1|1]; py[rt]=py[rt<<1] + py[rt<<1|1]; } void updata(int rt, int left, int right, int l, int r, int t) { if(left==l && right==r){ double x=px[rt], y=py[rt]; px[rt]=x*cos(t*pi/180) + y*sin(t*pi/180); py[rt]=-x*sin(t*pi/180) + y*cos(t*pi/180); turn[rt]+=t; return; } down(rt); int mid=(left+right)>>1; if(mid<l) updata(rt<<1|1, mid+1, right, l, r, t); else{ updata(rt<<1, left, mid, l, mid, t); updata(rt<<1|1, mid+1, right, mid+1, r, t); } px[rt]=px[rt<<1] + px[rt<<1|1]; py[rt]=py[rt<<1] + py[rt<<1|1]; } int main() { //freopen("in.txt","r",stdin); int N,O,cnt=0; while(~scanf("%d%d", &N,&O)) { ms(turn,0); for(int i=2; i<=N; i++) angle[i]=180; if(cnt++) printf("\n"); buildline(1,1,N); int a,b; while(O--) { scanf("%d%d", &a,&b); a++; int t=angle[a]-b; angle[a]=b; updata(1,1,N,a,N,t); printf("%.2lf %.2lf\n", px[1],py[1]); } } return 0; }