zoukankan      html  css  js  c++  java
  • POJ2991

    题目链接:https://vjudge.net/problem/POJ-2991

    知识准备:

    1、向量旋转公式:向量(x,y)逆时针旋转角度A,则旋转后的向量为(x*cos A-y*sin A, x*sin A+y*cos A).

    详见:https://www.zybang.com/question/143ceaa20d3942f3c6dbe9415dd81d0a.html

    2、PI可用这一行代码取得:

    const double PI=acos(-1.0);

    解题思路:思路来源于:http://www.cnblogs.com/staginner/archive/2012/04/07/2436436.html。

    在此处 struct point pt[rt] 是rt对应的向量的坐标。

    以结点间的向量为基础建立线段树。

    第48行,if()里面的判断条件是个易错点,一开始没有把l-1,所以错了。

    这是一道好题,值得重复做。

    AC代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <cmath>
     5 using namespace std;
     6 #define lson l,m,rt<<1
     7 #define rson m+1,r,rt<<1|1
     8 const int maxn=10000+3;
     9 const double PI=acos(-1.0);
    10 int totlen[maxn],len[maxn],degree[maxn];
    11 int rd[maxn<<2];
    12 int n,c;
    13 struct point{
    14     double x,y;
    15 }pt[maxn<<2];
    16 double getrad(int a){
    17     return (double)a/180*PI;
    18 }
    19 void Rotate(double &dx,double &dy,double rad){
    20     double x=dx,y=dy;
    21     dx=x*cos(rad)-y*sin(rad);
    22     dy=x*sin(rad)+y*cos(rad);
    23 }
    24 void pushup(int rt){
    25     pt[rt].x=pt[rt<<1].x+pt[rt<<1|1].x;
    26     pt[rt].y=pt[rt<<1].y+pt[rt<<1|1].y;
    27 }
    28 void pushdown(int rt){
    29     if(rd[rt]){
    30         double rad=getrad(rd[rt]);
    31         rd[rt<<1]+=rd[rt];
    32         rd[rt<<1|1]+=rd[rt];
    33         Rotate(pt[rt<<1].x,pt[rt<<1].y,rad);
    34         Rotate(pt[rt<<1|1].x,pt[rt<<1|1].y,rad);
    35         rd[rt]=0;
    36     }
    37 }
    38 void build(int l,int r,int rt){
    39     rd[rt]=0;
    40     pt[rt].x=0;     pt[rt].y=totlen[r]-totlen[l-1];
    41 //    printf("build: l = %d, r = %d, pt[%d].x = %lf, pt[%d].y = %lf
    ",l,r,rt,pt[rt].x,rt,pt[rt].y);
    42     if(l==r)    return;
    43     int m=(l+r)>>1;
    44     build(lson);
    45     build(rson);
    46 }
    47 void update(int L,int R,int delta,int l,int r,int rt){
    48     if(L<=l-1&&r<=R){
    49         double rad=getrad(delta);
    50         Rotate(pt[rt].x,pt[rt].y,rad);
    51         rd[rt]+=delta;
    52 //        printf("l = %d, r = %d, pt[%d].x = %lf,pt[%d].y = %lf
    ",l,r,rt,pt[rt].x,rt,pt[rt].y);
    53         return;
    54     }
    55     if(l==r)    return;
    56     pushdown(rt);
    57     int m=(l+r)>>1;
    58     if(L<=m)    update(L,R,delta,lson);
    59     if(m<R)     update(L,R,delta,rson);
    60     pushup(rt);
    61 }
    62 int main(){
    63 
    64     while(scanf("%d%d",&n,&c)==2){
    65         int s,a;
    66         for(int i=1;i<=n;i++){
    67             scanf("%d",&len[i]);
    68             totlen[i]=totlen[i-1]+len[i];
    69         }
    70         build(1,n,1);                  //_______________________
    71         for(int i=0;i<=n;i++)   degree[i]=0;
    72         while(c--){
    73             scanf("%d%d",&s,&a);
    74             a-=180;
    75             int delta=a-degree[s];
    76             degree[s]=a;
    77             update(s,n,delta,1,n,1);
    78             printf("%.2lf %.2lf
    ",pt[1].x,pt[1].y);
    79         }
    80         printf("
    ");
    81     }
    82     return 0;
    83 }
    View Code
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    八数码难题 (codevs 1225)题解
    小木棍 (codevs 3498)题解
    sliding windows (poj 2823) 题解
    集合删数 (vijos 1545) 题解
    合并果子 (codevs 1063) 题解
    等价表达式 (codevs 1107)题解
    生理周期 (poj 1006) 题解
    区间 (vijos 1439) 题解
    区间覆盖问题 题解
    种树 (codevs 1653) 题解
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7152996.html
Copyright © 2011-2022 走看看