poj 3258 River Hopscotch

点击打开链接poj 3258


思路:二分

分析:
1 题目意思是有一条长度为L的河流,河里有n个石头,现在有奶牛从河的起点0,通过跳跃石头到达终点n+1;现在有一个人,想测掉m个石头,然后求两块石头之间的距离的最小值中的最大值。
2 很明显如果m = 0 , 那么ans就是所有石头间距的最小值min,如果m = n 那么ans就是L ; 现在由于0=<m<=n,所以ans肯定会在[min , L]之间,所以只要在这个区间二分答案,然后找到可以去掉的石头数和m做比较即可
3 如果假设求出删除的石头数为k ,如果k > m ,那么right = mid;如果 k = m , 肯定的是如果另right = mid,那么接下来的k 肯定是小于m的肯定不满足,所以只能left = mid+1 ; 如果k < m ,那么left = mid;
所以有 k > m , right = mid;
k <= m , left = mid+1;

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;

#define MAXN 50010

int l , n , m;
int dis[MAXN];

int judge(int num){
   int count = 0;
   int pos = 0;
   for(int i = 1 ; i <= n+1 ; i++){
      if(dis[i]-dis[pos] <= num)/*求出可以删除的石头数*/
        count++;
      else
        pos = i;
   }
   return count;
}

void solve(){
   int left , right , mid;
   sort(dis , dis+n+2);
   
   left = 0x7FFFFFFF;
   for(int i = 1 ; i <= n+1 ; i++)
      left = min(left , dis[i]-dis[i-1]);
   right = l;

   if(m == 0){
     printf("%d\n" , left);
     return;
   }
   if(m == n){
     printf("%d\n" , l);
     return;
   }
   while(left < right){
      mid = left + (right-left)/2;
      int tmp = judge(mid);
      if(tmp > m)
        right = mid;
      else
        left = mid+1;
   }  
   printf("%d\n" , left);
}

int main(){
   while(scanf("%d%d%d" , &l , &n , &m) != EOF){
      dis[0] = 0;
      for(int i = 1 ; i <= n ; i++)
         scanf("%d" , &dis[i]);
      dis[n+1] = l;
      solve();
   }
   return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值