poj 2991 线段树 成段更新 + 向量旋转

题目链接: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;
}


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/observadores/article/details/53457169
个人分类: 线段树
上一篇poj 1113 Wall
下一篇课程设计-多种排序方式
想对作者说点什么? 我来说一句

线段树函数

2013年07月27日 1KB 下载

poj 2763 housewife Wind

2011年06月27日 4KB 下载

线段树题目

2012年07月16日 16KB 下载

线段树.pdf

2016年12月05日 288KB 下载

POJ2777 个人代码

2013年11月16日 1KB 下载

计算向量旋转矩阵的代码

2010年10月15日 1KB 下载

欧拉角、四元数与旋转向量

2017年08月17日 10.31MB 下载

acm_code_20053565

2008年11月29日 706KB 下载

ACM程序模板 from poj

2010年01月07日 135KB 下载

没有更多推荐了,返回首页

关闭
关闭