zoukankan      html  css  js  c++  java
  • 拼接游戏

    题目大意:

      给出一段由N个线段首尾相接而成的绳子,其中第 i 条线段(从1开始)是由点 Pi-1 和 点 Pi 相连而成,一开始绳子从原点向y轴正方向延伸,现在要对绳子做M次修改,每次修改会把第u + 1条线段调整到第u条线段逆时针方向w度的位置,其他线段之间的关系不变,要求输出每次修改后点 PN 的坐标。

      输入:第一行N,M(N,M <= 10000);第二行N个整数,表示这些线段的长度(长度为1~99之间的整数);接下来M行每行两个整数u,w(0 < u < N,0 <= w < 360)。

      输出:对于每次修改输出一行,包含两个两位小数,表示点 PN 的坐标。

    分析:

      通过观察可以发现,当第k条线段旋转了x度,其他线段之间角度关系不变的情况下,第k + 1 ~ N条线段相对于第k条线段没有发生改变,而相对于平面直角坐标系则是旋转了x度,且在第k + 1 ~ N条线段中,任意多个线段组成的图形修改前后形状没有发生改变,且相对于修改之前旋转了x度!把所有的线段用向量(x,y)来表示,那么每次操作就是将第k ~ N条线段进行旋转,然后输出所有线段表示的向量的和。

      因为N,M <= 10000,很显然会想到用NlogN的做法,而通过上面的分析,那么这个问题就转换成了区间修改和区间求和,修改会麻烦一点,因为不同的线段改的都不一样,但是有一个共同点就是旋转的角度一样,用线段树来维护,lazy-tag中记录角度就好了。线段树每个节点的x,y表示该节点所代表的区间的所有的向量的和,也可以把它看作一个向量。

    代码:

     1 #include <cstdio>
     2 #include <cmath>
     3 using namespace std;
     4 const double pi = acos (-1);
     5 struct tree {
     6     double x, y, lazy;
     7 } t[1000000];
     8 int n, m, u, w, len[10010];
     9 double degree (double ox, double oy) {
    10     return atan (ox / oy) + (oy < 0 ? pi : 0);
    11 }
    12 double turn (double deg, double &ox, double &oy) {
    13     double tx = ox * cos (deg) - oy * sin (deg);
    14     double ty = ox * sin (deg) + oy * cos (deg);
    15     ox = tx, oy = ty;
    16 }
    17 inline void pushup (int o) {
    18     t[o].x = t[o << 1].x + t[o << 1 | 1].x;
    19     t[o].y = t[o << 1].y + t[o << 1 | 1].y;
    20 }
    21 inline void pushdown (int o) {
    22     int l = o << 1, r = o << 1 | 1;
    23     double deg = t[o].lazy;
    24     turn (deg, t[l].x, t[l].y); t[l].lazy += deg;
    25     turn (deg, t[r].x, t[r].y); t[r].lazy += deg;
    26     t[o].lazy = 0;
    27 }
    28 void build (int i, int left, int right) {
    29     if (left < right) {
    30         int mid = (left + right) >> 1;
    31         build (i << 1, left, mid);
    32         build (i << 1 | 1, mid + 1, right);
    33         pushup (i);
    34     }else t[i].x = 0, t[i].y = len[left];
    35 }
    36 int mleft, mright;
    37 double mdeg, mx, my;
    38 void modify (int i, int l, int r, int mid) {
    39     if (mleft <= l && mright >= r) {
    40         turn (mdeg, t[i].x, t[i].y);
    41         t[i].lazy += mdeg; return;
    42     }
    43     pushdown (i);
    44     if (mleft <= mid && mright >= l)
    45         modify (i << 1, l, mid, (l + mid) >> 1);
    46     if (mright > mid && mleft <= r)
    47         modify (i << 1 | 1, mid + 1, r, (r + mid + 1) >> 1);
    48     pushup (i);
    49 }
    50 void mturn (int left, int right, double deg) {
    51     mleft = left, mright = right; mdeg = deg;
    52     modify (1, 1, n, (1 + n) >> 1);
    53 }
    54 void ask (int i, int l, int r, int mid) {
    55     if (mleft <= l && mright >= r) {
    56         mx += t[i].x, my += t[i].y;
    57         return;
    58     }
    59     pushdown (i);
    60     if (mright >= l && mleft <= mid)
    61         ask (i << 1, l, mid, (l + mid) >> 1);
    62     if (mleft <= r && mright > mid)
    63         ask (i << 1 | 1, mid + 1, r, (r + mid + 1) >> 1);
    64 }
    65 void askxy (int left, int right) {
    66     mleft = left, mright = right; mx = my = 0;
    67     ask (1, 1, n, (1 + n) >> 1);
    68     if (abs (mx) <= 0.001) mx = 0;
    69     if (abs (my) <= 0.001) my = 0;
    70 }
    71 int main () {
    72     scanf ("%d %d", &n, &m);
    73     for (int i = 1; i <= n; i++)
    74         scanf ("%d", &len[i]);
    75     build (1, 1, n);
    76     for (int i = 0; i < m; i++) {
    77         scanf ("%d %d", &u, &w);
    78         askxy (u, u);
    79         double deg = degree (mx, my);
    80         askxy (u + 1, u + 1);
    81         deg = pi * w / 180 - (deg + pi - degree (mx, my));
    82         mturn (u + 1, n, deg);
    83         askxy (1, n);
    84         printf ("%.2lf %.2lf
    ", mx, my);
    85     }
    86 }
  • 相关阅读:
    Elasticsearch (二) 索引
    Elasticsearch (一)搭建与启动
    IDEA 插件
    IDEA 导入华丽的皮肤
    Tomcat https 访问
    oracle系统视图SQL语句整理
    Java内存优化和性能优化的几点建议
    Tomcat配置SSL证书
    sublime集成MinGW,打造C/C++开发环境
    一个简单的Vue.js组件开发示例
  • 原文地址:https://www.cnblogs.com/lightning34/p/4314223.html
Copyright © 2011-2022 走看看