poj 3258

/*
  题意:从一个河岸跳到另外一个河岸,两个河岸之间的距离为l,中间有n个石头,每次只能从河岸和石头或者石头和石头之间跳跃,求去除最多m个石头,使得跳跃的最小距离最大。
  要注意,m是可以为0的,n也一样。
*/
#include <iostream> #include <algorithm> #include <cstdio> #define range(i,a,b) for (int i=a;i<=b;i++) using namespace std; const int maxL = 1000000000; const int maxN =50000; int last[maxN + 1]; int pos[maxN + 10]; int n,m,l; bool check(int dis) { int ans(0); int eon(n); range(i,1,n+1) last[i] = pos[i]- pos[i-1]; while(last[n+1] < dis && eon>=1) { last[n+1] += last[eon--]; ans++; } range(i,1,eon) if (last[i] < dis) { ans++; last[i+1] += last[i]; } return ans<=m; } int main() { cin>>l>>n>>m; range(i,1,n) { scanf("%d",&pos[i]); } pos[0] = 0; pos[n+1] = l; sort(pos,pos+n+2); int L(0),R(l);
   /*
    这里,如果r设置为maxl,假如n为0的情况,输出的就是maxl,显然是错误的
    下面有两组测试数据,可以检测出这个错误
    10 1 1
    6

    10 0 0
   */
range(c,1,100) { int Mid = (L+R)>>1; if (check(Mid)) { L = Mid; } else { R = Mid; } } if (check(R)) { //if do not output in this way,may the answer be l && r=l+1,then it will always output l //can not use cout<<(l+r)/2 cout<<R<<endl; } else { cout<<L<<endl; } return 0; }
原文地址:https://www.cnblogs.com/dandi/p/4063525.html