把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

noi.ac-CSP模拟Day5T2 灯

 

 

算是一道思维题吧,没有什么算法在里面。

之前想的是,能走的话就尽量走远,走过去开灯然后再回去关灯,然后再走,每一段路要走3次。

 

 

然而,“能走的话就尽量走远”只是yy的一个贪心,没有任何依据。假设在中间找一个过渡点的话,路程应该是长这个样子的:

 

总路程还是3倍距离,没有改变诶。

所以只要你认认真真地,正正常常地走路,不绕圈圈,所走的路程都是3倍距离。

所以只需要判断能不能走到就可以了。

既然如此,那就可以随便开灯了(大雾)

(没有开玩笑啊)是真的可以随便开灯了,因为只是要判断能否走到,就用不着节约了。

从左走到右的时候,依次开灯,每次开灯之后要保证至少走到下一个点
回去的时候不用管
再一次从左走到右关灯,这一次走的时候依靠的是前面没有被关的灯光
前面延伸到左边最远的灯光要保证自己所在的位置有灯

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<string>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<cstdlib>
 9 using namespace std;
10 #define N 300005
11 #define ll long long 
12 #define INF 0x3f3f3f3f
13 int n;
14 int p[N],r[N];
15 /*
16 从左走到右的时候,依次开灯,每次开灯之后要保证至少走到下一个点
17 回去的时候不用管
18 再一次从左走到右关灯,这一次走的时候依靠的是前面没有被关的灯光
19 前面延伸到左边最远的灯光要保证自己所在的位置有灯 
20 */
21 int main()
22 {
23     scanf("%d",&n);
24     for(int i=1;i<=n;i++)
25         scanf("%d %d",&p[i],&r[i]);
26     int far=p[1];//能够延伸到右边最远的灯光坐标 保证能够走到终点 
27     for(int i=2;i<=n;i++)
28     {
29         far=max(far,p[i-1]+r[i-1]);
30         if(far<p[i])
31         {
32             puts("-1");
33             return 0;
34         }
35     } 
36     far=p[n];//能够延伸到左边最远的灯光坐标 保证能够关灯 
37     for(int i=n;i>=2;i--)
38     {
39         far=min(far,p[i]-r[i]);
40         if(far>p[i-1])
41         {
42             puts("-1");
43             return 0;
44         }
45     }
46     printf("%lld\n",(p[n]-p[1])*3ll);
47     return 0;
48 }
Code

 

 

 

posted @ 2019-11-05 10:01  Starlight_Glimmer  阅读(166)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end