codeforces 957 C Three-level Laser

题意:

说的是一个电子云的三种状态,但是这不重要。

简单来说,就是在一个升序的序列中找三个数x,y,z,x和z的值之差不超过u,然后使得(z – y) / (z – x)最大。

思路:

使得(z – y)/(z – x)最大,那么y与x要尽量接近,并且z – x尽量大,一个比较显然的例子是8/9大于7/8。

对于每一个x,紧邻它的下一个数就是y,然后二分查找最大的小于等于x+u的数字,然后取(z – y) / (z – x)的最大值。

我的失误在于考虑到了最后可能x与z相等,但是没有考虑到y与z也可能相等,这是思维不严谨的地方,mark!

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <set>
 4 #include <algorithm>
 5 #include <vector>
 6 using namespace std;
 7 
 8 vector<int> v;
 9 
10 int main()
11 {
12     int n,d;
13     
14     scanf("%d%d",&n,&d);
15     
16     double ans = -1;
17     
18     for (int i = 0;i < n;i++)
19     {
20         int x;
21         scanf("%d",&x);
22         v.push_back(x);
23     }
24     
25     for (int i = 0;i < n - 2;i++)
26     {
27         int x = v[i],y = v[i+1];
28         
29         int p = lower_bound(v.begin(),v.end(),x+d) - v.begin();
30         
31         if (p == n) p--;
32         while (v[p] > x + d) p--;
33         
34         int z = v[p];
35         
36         if (x >= z || y >= z) continue;
37         
38         double tmp = 1.0 * (z - y) / (z - x);
39         
40         //printf("%d %d %d
",x,y,z);
41         
42         ans = max(ans,tmp);
43     }
44     
45     if (ans < 0) printf("-1");
46     else printf("%.11f",ans);
47     
48     return 0;
49 }
原文地址:https://www.cnblogs.com/kickit/p/8809596.html