题目链接:http://poj.org/problem?id=2991
输入数据:
n条线段,c条指令
n条线段的长度li(最初的线段都是在y轴上的)
c条的指令是s,a,表示第s条线段和第s+1条线段的夹角调整为a度
每执行完一条命令输出最后一条线段末尾的坐标
注意:输出的时候,c++中用%lf,g++中用%f。
keep[maxn]保存第i条边与i-1边的夹角(初始化为180°)
每次线段要旋转的角度由a-keep[s]得到(记得更新keep[s]=a)
向量公式
t= a-keep[s];//t的正负不影响结果
x1=x0*cos(t*PI/180) - y0*sin(t*PI/180);
y1=y0*cos(t*PI/180) + x0*sin(t*PI/180);
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
using namespace std;
const int maxn = 10010;
const double PI = acos(-1.0);//求出π的值
struct node
{
intl;
intr;
doublex;
doubley;
intangle;
}tree[maxn*4];
int n,c;
int len[maxn];
int keep[maxn];
void turn(int p,int t)
{
doublex0 = tree[p].x;
doubley0 = tree[p].y;
tree[p].x= x0*cos(t*PI/180) - y0*sin(t*PI/180);// sin,cos函数里面用的都是弧度,转换
tree[p].y= y0*cos(t*PI/180) + x0*sin(t*PI/180);
}
void create(int p,int l,int r)
{
tree[p].l= l;
tree[p].r= r;
if(l== r)
{
tree[p].x= 0;
tree[p].y= len[l];
return;
}
intmid = (l+r)>>1;
create(p<<1,l,mid);
create(p<<1|1,mid+1,r);
tree[p].x= 0;
tree[p].y= tree[p<<1].y + tree[p<<1|1].y;
tree[p].angle= 0;
}
void pushdown(int p)
{
if(tree[p].angle!= 0)
{
turn(p<<1,tree[p].angle);
turn(p<<1|1,tree[p].angle);
tree[p<<1].angle+= tree[p].angle;
tree[p<<1|1].angle+= tree[p].angle;
tree[p].angle= 0;
}
}
void update(int p, int l, int r, int TurnA)
{
if(tree[p].l== l && tree[p].r == r)
{
tree[p].angle+= TurnA;
turn(p,TurnA);
return;
}
pushdown(p);
intmid = (tree[p].l+tree[p].r)>>1;
if(r<= mid)
update(p<<1,l,r,TurnA);
elseif(l > mid)
update(p<<1|1,l,r,TurnA);
else
{
update(p<<1,l,mid,TurnA);
update(p<<1|1,mid+1,r,TurnA);
}
tree[p].x= tree[p<<1].x + tree[p<<1|1].x;
tree[p].y= tree[p<<1].y + tree[p<<1|1].y;
}
int main()
{
ints,a;
intflag=0;
while(~scanf("%d%d",&n,&c))
{
if(flag)
printf("\n");
flag= 1;
for(inti = 1; i <= n; i++)
{
scanf("%d",&len[i]);//第i条边的长度
keep[i]= 180;//第i条边与前一条边的夹角
}
create(1,1,n);
for(inti = 0; i < c; i++)
{
scanf("%d%d",&s, &a);
s++;
update(1,s,n,a-keep[s]);
keep[s]= a;
printf("%.2lf%.2lf\n", tree[1].x, tree[1].y);
}
}
return0;
}