标签:require alt std str his started 超时 ever 最大的
6 1 2 2 25 3 3 11 2 18
4 11
就是一个青蛙要跳的对岸,然后河流中间有M块石头,然后最多可以跳k次,问这个青蛙最短需要跳多远才可以保证不掉下去。按照我的想法,m个石头,都被跳到的话需要跳M+1次。那么如果k >= M+1次,那就是找到两块石头之间距离最大的哪一个就可以了。但是如果k < M+1次的话呢,青蛙就需要一次跳过多的石头,M+1 - k.就可以知道青蛙需要越过多少块石头,既在多少块石头上面不能停留。所以呢,我就需要每次去遍历,找到最近的相隔一块石头的两块石头。那么我就需要循环遍历(M+1-k) * (M+1) 次左右了。这肯定不行啊,大致估计一下时间复杂度500000 * 500000,GG,肯定会超时。想了一想,想不到好办法,然后百度,说用二分,去二分所要求的跳跃能力,然后每次检验一下能不能跳过去。这样再算一下时间,500000 * log(1000000000 ),这不会超时。应该记住的 n*2 的时间优化多半是优化到n*log(n), 而log(n)的优化,多半是二分,或者一些STL的数据结构。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 500010; 6 7 int ans[N]; 8 9 int ll, nn, mm; 10 11 12 bool judge (int dis) { 13 int tx = 0, i, ty = 0; 14 for (int i = 1; i <= mm; i++) { 15 while (ty <= nn + 1 && ans[ty] - ans[tx] <= dis) ty++; 16 17 ty --; 18 tx = ty; 19 } 20 return ty == nn + 1; 21 } 22 23 int main () { 24 25 while (~scanf("%d %d %d", &ll, &nn, &mm)) { 26 27 for (int i = 1; i <= nn; i++) { 28 scanf("%d", &ans[i]); 29 } 30 ans[0] = 0; ans[nn+1] = ll; 31 sort(ans, ans + nn +1); 32 int L = 0, R = ll; 33 while (L <= R) { 34 int mid = (L + R) >> 1; 35 if (judge(mid)) { 36 R = mid - 1; 37 } else L = mid + 1; 38 } 39 printf("%d\n", L); 40 } 41 return 0; 42 }
标签:require alt std str his started 超时 ever 最大的
原文地址:https://www.cnblogs.com/gznb/p/11212382.html