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\n",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 }
康复训练中~欢迎交流!