• [CodeForces-555D]Case of a Top Secret


    题目大意:
      一个直线上有n个钉子,现在分别在某个钉子上挂一段系有重物的绳子,对这个物体是加一个向右的力,使它作圆周运动,
      绳子最终一定会缠在一些钉子上并围绕某一个钉子做圆周运动。
      问最终会围哪个钉子做运动。

    思路:
      考虑暴力模拟,每次二分查找绳子会转到哪里,并对绳子减去区间的长度,这样能拿到10分。
      显然绳子有些时候会在同样一段区间上转很多次,因此我们可以取模避免重复减,这样能拿到30分。
      观察发现每次绳子能够旋转的范围是在不断缩减的,而且左端点越来越大,右端点越来越小,这样我们可以每次缩减一下二分的范围,这样就能拿到100分。
      注意第一次旋转时不能直接取模。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<vector>
     4 #include<algorithm>
     5 inline int getint() {
     6     register char ch;
     7     register bool neg=false;
     8     while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
     9     register int x=ch^'0';
    10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    11     return neg?-x:x;
    12 }
    13 const int N=200001;
    14 struct Point {
    15     int x,id;
    16     bool operator < (const int &another) const {
    17         return x<another;
    18     }
    19     bool operator < (const Point &another) const {
    20         return x<another.x;
    21     }
    22 };
    23 std::vector<Point> v;
    24 int x[N];
    25 int main() {
    26     const int n=getint();
    27     int m=getint();
    28     for(register int i=1;i<=n;i++) {
    29         v.push_back((Point){x[i]=getint(),i});
    30     }
    31     std::sort(v.begin(),v.end());
    32     while(m--) {
    33         std::vector<Point>::iterator b=v.begin(),e=v.end();
    34         int last=0,i=getint(),l=getint();
    35         bool d=true;
    36         last=i;
    37         e=std::lower_bound(b,e,x[i]+l+1);
    38         i=(e-1)->id;
    39         l-=x[i]-x[last];
    40         if(last==i) {
    41             b=std::lower_bound(b,e,x[i]-l);
    42             i=b->id;
    43             l-=x[last]-x[i];
    44         }
    45         while(last!=i) {
    46             if(d) {
    47                 last=i;
    48                 e=std::lower_bound(b,e,x[i]+l+1);
    49                 i=(e-1)->id;
    50                 if(i==last) {
    51                     d^=true;
    52                     goto Left;
    53                 }
    54                 if((l/(x[i]-x[last]))&1) {
    55                     d^=true;
    56                 } else {
    57                     std::swap(last,i);
    58                 }
    59                 l%=x[i]-x[last];
    60             }
    61             Left:
    62             if(!d) {
    63                 last=i;
    64                 b=std::lower_bound(b,e,x[i]-l);
    65                 i=b->id;
    66                 d^=true;
    67                 l-=x[last]-x[i];
    68             }
    69         }
    70         printf("%d
    ",i);
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    (转)Apache与Tomcat 区别联系
    (转)JAVA排序汇总
    (转)Java线程:大总结
    (转)Java线程:新特征-原子量,障碍器
    (转)Java线程:新特征-条件变量
    oracle中的not in和not exists注意事项
    oracle字符乱码的解决方法
    线刷和卡刷的区别
    nexus5刷机
    linux上复制行到另一个文件
  • 原文地址:https://www.cnblogs.com/skylee03/p/7600473.html
Copyright © 2020-2023  润新知