码迷,mamicode.com
首页 > 其他好文 > 详细

[ZHOJ1955]lj的锁

时间:2017-09-27 11:34:51      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:端点   blog   避免   而且   多次   als   cto   题目   思路   

题目大意:
  一个直线上有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             last=i;
42             b=std::lower_bound(b,e,x[i]-l);
43             i=b->id;
44             l-=x[last]-x[i];
45         }
46         while(last!=i) {
47             if(d) {
48                 last=i;
49                 e=std::lower_bound(b,e,x[i]+l+1);
50                 i=(e-1)->id;
51                 if(i==last) {
52                     d^=true;
53                     goto Left;
54                 }
55                 if((l/(x[i]-x[last]))&1) {
56                     d^=true;
57                 } else {
58                     std::swap(last,i);
59                 }
60                 l%=x[i]-x[last];
61             }
62             Left:
63             if(!d) {
64                 last=i;
65                 b=std::lower_bound(b,e,x[i]-l);
66                 i=b->id;
67                 d^=true;
68                 l-=x[last]-x[i];
69             }
70         }
71         printf("%d\n",i);
72     }
73     return 0;
74 }

 

[ZHOJ1955]lj的锁

标签:端点   blog   避免   而且   多次   als   cto   题目   思路   

原文地址:http://www.cnblogs.com/skylee03/p/7600473.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!