国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > 互联网 > poj 2991 Crane(线段树)

poj 2991 Crane(线段树)

来源:程序员人生   发布时间:2014-10-10 08:00:01 阅读次数:2758次

题目链接:poj 2991 Crane

题目大意:就是有一个机械手臂,有n结,给定每节的长度,一开始为垂直的。有m次操作,每次将x关节变成角度d,并且输出手臂末端的坐标。

解题思路:点的旋转公式(r为逆时针的角度):

  • x=x?cos(r)?y?sin(r)
  • y=x?sin(r)+y?cos(r)

没有做过类似的题目,线段树每个节点记录的为每节旋转的角度以及单节末端的位置。每次旋转新的角度,需要根据前一个节点的角度和当前节点的角度来计算(因为它不是再旋转d,而是变成角度d

#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const double pi = atan(1.0) * 4; #define lson(x) ((x)<<1) #define rson(x) (((x)<<1)|1) const int maxn = 10005; int lc[maxn * 4], rc[maxn * 4], s[maxn * 4], v[maxn * 4]; double xi[maxn * 4], yi[maxn * 4]; void rotate (int u, int deg) { double r = deg * pi / 180; double x = xi[u] * cos(r) - yi[u] * sin(r); double y = xi[u] * sin(r) + yi[u] * cos(r); xi[u] = x; yi[u] = y; s[u] = (s[u] + deg) % 360; v[u] = (v[u] + deg) % 360; } void pushup (int u) { xi[u] = xi[lson(u)] + xi[rson(u)]; yi[u] = yi[lson(u)] + yi[rson(u)]; } void pushdown (int u) { if (s[u]) { rotate(lson(u), s[u]); rotate(rson(u), s[u]); s[u] = 0; } } void build (int u, int l, int r) { lc[u] = l; rc[u] = r; s[u] = v[u] = 0; if (l == r) { xi[u] = 0; scanf("%lf", &yi[u]); return ; } int mid = (l + r) / 2; build (lson(u), l, mid); build (rson(u), mid + 1, r); pushup(u); } int query (int u, int pos) { if (lc[u] == rc[u]) return v[u]; pushdown(u); int mid = (lc[u] + rc[u]) / 2; if (pos <= mid) return query(lson(u), pos); else return query(rson(u), pos); pushup(u); } void modify (int u, int l, int r, int deg) { if (l <= lc[u] && rc[u] <= r) { rotate(u, deg); return; } pushdown(u); int mid = (lc[u] + rc[u]) / 2; if (l <= mid) modify(lson(u), l, r, deg); if (r > mid) modify(rson(u), l, r, deg); pushup(u); } int N, M; int main () { int cas = 0, d, r; while (scanf("%d%d", &N, &M) == 2) { if (cas++) printf(" "); build (1, 0, N-1); while (M--) { scanf("%d%d", &d, &r); r = (query(1, d - 1) + 180 + r - query(1, d)) % 360; modify(1, d, N - 1, r); printf("%.2lf %.2lf ", xi[1], yi[1]); } } return 0; }
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生