Shopee:Shopee的零食柜(C++语言实现)

题目描述

shopee的零食柜,有着各式各样的零食,但是因为贪吃,小虾同学体重日益增加,终于被人叫为小胖了。
他终于下定决心减肥了,他决定每天晚上去操场跑两圈,但是跑步太累人了,他想转移注意力,忘记痛苦。
正在听着音乐的他,突然有个想法,他想跟着音乐的节奏来跑步。
音乐有7种音符,对应的是1到7,那么他对应的步长就可以是1-7分米,这样的话他就可以转移注意力了。
但是他想保持自己跑步的速度,在规定时间m分钟跑完。
为了避免被累死,他需要规划他每分钟需要跑过的音符,这些音符的步长总和要尽量小。
下面是小虾同学听的歌曲的音符,以及规定的时间,你能告诉他每分钟他应该跑多少步长?
  • 输入描述
第一行输入n(1≤n≤1000000,表示音符数),m(1<=m<1000000,m<=n)组成
第二行有n个数,表示每个音符(1<=f<=7)
  • 输出描述
输出每分钟应该跑的步长
  • 示例
输入:
8 5
6 5 6 7 6 6 3 1

输出:
11

说明:
6|5 6|7|6|6 3 1为最优解。如果小于11,必然分段大于5。

二分查找的变形

确定上下界,下界是取序列的最小值,上界则为序列中所有元素的和值。二分查找所依据的是当前值能分块的数目跟目标块的大小关系。

def steps_by_minute(seq, block, low, high):
    length = len(seq)
    mid = low
    while low <= high:
        mid = (low+high) >> 1
        count, flag = 0, True
        si = 0
        while si < length:
            total = 0
            while si < length and total+seq[si] <= mid:
                total += seq[si]
                si += 1
            count += 1
            if count > block:
                flag = False
                break
        if flag:
            high = mid - 1
        else:
            low = mid + 1
    return mid


if __name__ == '__main__':
    num, block = list(map(int, input().strip().split()))
    seq = list(map(int, input().strip().split()))

    print(steps_by_minute(seq, block, max(seq), sum(seq)))

Python实现时间通过不了,使用C++实现。

#include <iostream>
#include <vector>

using namespace std;

int steps_by_value(vector<int> seq, int num,  int block, int low, int high)
{
    int mid;
    while(low<=high)
    {
        mid = (low+high) >> 1;
        int count =0;
        bool flag = true;
        int index = 0;
        while(index<num)
        {
            int total = 0;
            while(index<num && total+seq[index]<=mid)
            {
                total += seq[index];
                index += 1;
            }
            count += 1;
            if(count > block)
            {
                flag = false;
                break;
            }
        }
        if(flag)
            high = mid -1;
        else
            low = mid + 1;
    }
    return mid;
}

int main()
{
    int num, block;
    cin >> num >> block;
    vector<int> seq(num, 0);
    int left=0, right=0;
    for(int si=0;si<num;si++)
    {
        cin >> seq[si];
        if(left < seq[si])
            left = seq[si];
        right += seq[si];
    }
    int res = steps_by_value(seq, num, block, left, right);
    cout << res;

    return 0;
}

(最近更新:2019年08月30日)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值