愤怒的奶牛2(angry)

题目描述

贝茜这头奶牛设计了她所认为的下一个热门视频游戏—“愤怒的奶牛”。她认为这是她完全原创的:玩家将一个弹弓射到一个一维的场景中,该场景由位于数字线上各个点的一组干草包组成。每只奶牛都有足够的力量引爆其落地地点附近的干草包,我们的目的是使用一系列奶牛引爆所有的干草包。
有N捆干草包位于这一行的不同整数位置x1,x2,…,xN,如果一头奶牛以能量R着陆在了数轴上的任意一个位置x,那么会引起半径为R(R-x…R+x)的爆炸,并摧毁范围内的所有干草包。
一共有K头奶牛允许被用来作为炮弹,每头奶牛的能量R都相同。请帮忙决定这个最小的能量,使得用这K头奶牛可以摧毁所有的干草包。

输入

第一行包含两个整数N,K(1<=N<=50,000,1<=K<=10)
接下来N行,每行包含一个整数xi,表示每捆干草包的位置(0<=xi<=1,000,000,000)

输出

一行一个整数,表示最少所需要的每头奶牛的能量值R

样例输入

7 2
20
25
18
8
10
3
1

样例输出

5

思路:

这道题我们可以用二分算法来模拟能量值R,我们一旦遇到求最大最小值就要想到二分算法,但在二分算法前,按照方法,我们应该先用快速排序排一下,才能进行二分算法。

AC代码:

#include<bits/stdc++.h>  // 包含所有标准库头文件
using namespace std;

int n, k, r, l, sum, cnt;  // 变量声明:
                           // n-干草包数量,k-奶牛数量
                           // r/l-二分查找的左右边界
                           // sum-当前累计距离,cnt-所需奶牛数量
int a[50005];             // 存储干草包位置的数组

int main() {
    freopen("angry.in", "r", stdin);    // 重定向输入文件
    freopen("angry.out", "w", stdout);  // 重定向输出文件(修正:原代码中误写为"r")
    
    scanf("%d%d", &n, &k);             // 读取干草包数量和奶牛数量
    for(int i = 1; i <= n; i++) {      // 循环读取每个干草包的位置
        scanf("%d", &a[i]);
    }
    sort(a + 1, a + n + 1);            // 对干草包位置进行排序
    
    l = 0;                             // 初始化二分左边界为0
    r = INT_MAX;                       // 初始化二分右边界为最大整数值
    
    while(l <= r) {                    // 二分查找主循环
        int mid = (r + l) / 2;         // 计算中间值作为当前尝试的能量值
        cnt = 1, sum = 0;              // 初始化:至少需要1头奶牛,累计距离清零
        
        for(int i = 1; i < n; i++) {   // 遍历所有干草包
            sum += a[i + 1] - a[i];    // 累计相邻干草包的距离
            if(sum > mid * 2) {        // 如果累计距离超过当前能量覆盖范围
                cnt++;                 // 需要增加一头奶牛
                sum = 0;               // 重置累计距离
            }
        }
        
        if(cnt > k) {                  // 如果需要的奶牛数超过限制
            l = mid + 1;               // 增大能量值(右移左边界)
        } else {                       // 否则
            r = mid - 1;               // 尝试减小能量值(左移右边界)
        }
    }
    
    printf("%d", l);                   // 输出最小满足条件的能量值
    return 0;                          // 程序正常结束
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值