zoukankan      html  css  js  c++  java
  • POJ 2991(线段树)

    题意:有n根长度不尽相同的棍子,初始时它们首尾垂直相连,标号为1--n,第一根棍子的下端坐标为(0,0),上端坐标为(0,len[1]),其余棍子依次类推。接下来执行C此旋转,每次输入一个编号num和角度rad,使得第num根棍子和第num+1跟棍子间的逆时针角度变为rad度,求每次旋转后第n跟棍子端点的坐标。

    思路:主要是是对此题如何转化为线段树的问题,这是通过对每个结点所在区间进行处理。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <stack>
    #include <queue>
    #include <map>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    #define pi 3.141592653
    using namespace std;
    
    const int maxn = 40005;
    
    
    typedef long long LL;
    
    int N,C;
    int L[maxn];
    int S[maxn],A[maxn];
    
    double vx[maxn],vy[maxn];
    double ang[maxn];
    double pre[maxn];
    
    void init(int l,int r,int rt)
    {
       ang[rt] = vx[rt] = 0.0;
       if(r - l == 1) {
        vy[rt] = L[l];
       }
       else{
        int lch = rt*2+1;
        int rch = rt*2+2;
        int mid = (r + l )/2;
        init(l,mid,lch);
        init(mid,r,rch);
        vy[rt] = vy[lch] + vy[rch];
       }
    }
    
    void change(int s,double a,int rt,int l,int r)
    {
        if(s <= l) return ;
        else if(s < r){
            int lch = rt*2+1;
            int rch = rt*2+2;
            int mid = (l + r)/2;
            change(s,a,lch,l,mid);
            change(s,a,rch,mid,r);
            if(s <= mid) ang[rt] += a;
            double t = sin(ang[rt]);
            double c = cos(ang[rt]);
            vx[rt] = vx[lch] + (c*vx[rch] - t*vy[rch]);
            vy[rt] = vy[lch] + (t*vx[rch] + c*vy[rch]);
        }
    }
    
    void solve()
    {
        init(0,N,0);
        for(int i=1;i<N;i++) pre[i] =  pi;
        for(int i=0;i<C;i++){
            int s = S[i];
            double a = A[i]/360.0*2*pi;
            change(s,a-pre[s],0,0,N);
            pre[s] = a;
            printf("%.2f %.2f
    ",vx[0],vy[0]);
        }
    }
    
    int main()
    {
        while(scanf("%d%d",&N,&C)!=EOF){
        for(int i=0;i<N;i++){
            scanf("%d",&L[i]);
        }
        for(int i=0;i<C;i++){
            scanf("%d%d",&S[i],&A[i]);
        }
        solve();
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    pm2日志切割
    PM2常用命令
    Linux安装nodejs
    npm 修改源地址
    nodejs 生成验证码
    shell脚本解析json文件
    mysql添加用户并赋予权限命令
    Redis 配置密码
    JavaScript也是黑客技术?
    angular和vue的对比学习之路
  • 原文地址:https://www.cnblogs.com/jaszzz/p/12905912.html
Copyright © 2011-2022 走看看