基于POJ2991Crane问题对线段树的理解

来源:互联网 发布:ubuntu 升级软件包 编辑:程序博客网 时间:2024/06/03 18:56

题意:有一台起重机。我们把起重机看成由N条线段依次首尾相接而成。第i条线段的长度是Li。最开始,所有的线段都笔直连接,指向上方。

有C条操纵起重机的指令。指令i给出两个整数Si和Ai,效果是使线段Si和S(i+1)之间的角度变成Ai度。其中角度指的是线段Si开始逆时针旋转到S(i+1)所经过的角度,最开始时所有的角度都是180度。

按顺序执行这C条指令,在每条指令执行后,输出起重机的前端(第N条线段的断点)的坐标。假设起重机的支点的坐标是(0,0)。


思路:首先应该明确

1、一个点在绕原点旋转θ度之后的坐标为x=x0*cosθ-y0*sinθ,y=x0*sinθ+y0*cosθ。

2、如果将其中的某一段线段绕一个点旋转β度,那么这个线段上方的所有线段也都会绕这个点旋转β度。但是在题目中的旋转并不是绕一个定点进行的,所以就无法对旋转进行叠加,就不能够使用线段树解决问题,因此应该找其他思路,实际上旋转角还等于线段旋转前后所在直线的夹角,所以用向量表示线段那么所有的旋转操作就可以统一到一起了。

从线段树的角度出发,首先我们应当找到找到线段树的区间,应该保证每个节点都在这个区间里,从以上分析中我们能够明白节点就是用向量表示的每一段线段。线段树的优势是善于处理区间,所以我们应该思考线段树如何处理区间,在题目中对线段的操作只有旋转这一种,所以我们应该思考如何做好线段向量在旋转之后的位置和角度。即线段树区间状态的更新。


综上处理线段树的关键是在于寻找节点和更新节点和如何完成线段树的更新。

原创粉丝点击