《算法竞赛·快冲300题》每日一题:“松鼠与栗子”

这篇具有很好参考价值的文章主要介绍了《算法竞赛·快冲300题》每日一题:“松鼠与栗子”。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

算法竞赛·快冲300题》将于2024年出版,是《算法竞赛》的辅助练习册。
所有题目放在自建的OJ New Online Judge。
用C/C++、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。


松鼠与栗子” ,链接: http://oj.ecustacm.cn/problem.php?id=1852

题目描述

【题目描述】 现在有m棵栗子树,n只松鼠在等待栗子下落。
   第i棵树的第一个栗子在t[i],之后每p[i]秒都掉落一个。
   现在松鼠们希望最终能获得k个栗子,每只松鼠将选择一棵栗子树等待。
   不考虑松鼠移动到每棵树的时间,只考虑等待时间。
   请求出最优情况下的最少的等待时间,即松鼠选择最优情况下的n个栗子树进行等待,等待时间最小是多少。
【输入格式】 第一行为正整数m,n,k。1≤n≤m≤10000,1≤k≤10^7。
   第二行包含m个整数表示t[i]。
   第三行包含m个整数表示p[i],1≤t[i],p[i]≤100。
【输出格式】 输出一个数字表示答案。
【输入样例】

样例13 2 5
5 1 2
1 2 1

样例23 2 5
5 1 2
1 1 1

【输出样例】

样例14

样例23

题解

   这是一道很直接的二分题。等待时间越长,掉落栗子越多,所以等待时间对应的栗子数量是单调递增的,可以用二分法。猜一个最小等待时间x,用二分法找到x。
   用check(x)函数判断x时间是否掉落超过k个栗子。首先算出m颗树在x秒时一共掉落多少个栗子, 若栗子总数少于k, 返回false;如果超过k个,对m棵树掉落的栗子排序后,选择前n个与k比较。
【重点】 二分 。文章来源地址https://www.toymoban.com/news/detail-679941.html

C++代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int t[N], p[N];
int num[N];
int n, m, k;
bool check(int x){
    for(int i = 1; i <= m; i++)  {
        if(x >= t[i])  num[i] = (x - t[i]) / p[i] + 1;
        else           num[i] = 0;
    }
    long long sum = 0;
    sort(num + 1, num + 1 + m, greater<int>());  //从大到小排序
    for(int i=1; i<=n && i<=m; i++)  sum += num[i];
    return sum >= k;
}
int main(){
    cin >> m >> n >> k;
    if(n > m)  n = m;
    for(int i=1; i<=m; i++)  cin >> t[i];
    for(int i=1; i<=m; i++)  cin >> p[i];
    int L=0, R=1e9, ans=0;
    while(L <= R){
        int mid = (L + R) >> 1;
        if(check(mid))   ans = mid, R = mid - 1;
        else             L = mid + 1;
    }
    cout<<ans<<endl;
    return 0;
}

Java代码

import java.util.*;
public class Main {
    static int[] t = new int[10010];
    static int[] p = new int[10010];
    static int[] num = new int[10010];
    static int n, m, k;
    public static boolean check(int x) {
        for (int i = 1; i <= m; i++) {
            if (x >= t[i]) num[i] = (x - t[i]) / p[i] + 1;
            else num[i] = 0;
        }
        long sum = 0;
        Arrays.sort(num, 1, m + 1);
        for (int i=1; i<=n && i<=m; i++) sum += num[m - i + 1];
        return sum >= k;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        m = sc.nextInt();
        n = sc.nextInt();
        k = sc.nextInt();
        if (n > m) n = m;
        for (int i = 1; i <= m; i++) t[i] = sc.nextInt();
        for (int i = 1; i <= m; i++) p[i] = sc.nextInt();
        int L = 0, R = 1000000000, ans = 0;
        while (L <= R) {
            int mid = (L + R) >> 1;
            if (check(mid)) { ans = mid;  R = mid - 1; } 
            else  L = mid + 1;            
        }
        System.out.println(ans);
        sc.close();
    }
}

Python代码

t = [0] * (10010)
p = [0] * (10010)
num = [0] * (10010)
def check(x):
    for i in range(1, m + 1):
        if x >= t[i]:  num[i] = (x - t[i]) // p[i] + 1
        else:          num[i] = 0
    num.sort(reverse=True)
    sum = 0
    for i in range(1, n+1 if n<=m else m+1):   sum += num[i]
    return sum >= k
m, n, k = map(int, input().split())
t[1:] = [int(x) for x in input().split()]
p[1:] = [int(x) for x in input().split()]
L, R, ans = 0, 1000000000, 0
while L <= R:
    mid = (L + R) // 2
    if check(mid):
            ans = mid
            R = mid - 1
    else:   L = mid + 1
print(ans)

到了这里,关于《算法竞赛·快冲300题》每日一题:“松鼠与栗子”的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《算法竞赛·快冲300题》每日一题:“凑二十四”

    《 算法竞赛·快冲300题 》将于2024年出版,是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C++、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。 “ 凑二十四 ” ,链接: http://oj.ecustacm.cn/problem.php?id=1793 【题目描述】 给你n个数字,

    2024年02月11日
    浏览(37)
  • 罗勇军 → 《算法竞赛·快冲300题》每日一题:“排列变换” ← 贪心算法

    【题目来源】 http://oj.ecustacm.cn/problem.php?id=1812 http://oj.ecustacm.cn/viewnews.php?id=1023 【题目描述】 给定一个长度为 n 的排列 a,需要将这个排列变成 b。 每次可以选择一个数字往左移若干个位置。 请求出 最小需要移动的元素个数 。 【输入格式】 第一行为正整数 n,1≤n≤100000。

    2024年02月12日
    浏览(41)
  • 罗勇军 →《算法竞赛·快冲300题》每日一题:“乘积” ← 动态规划

    【题目来源】 http://oj.ecustacm.cn/problem.php?id=1781 http://oj.ecustacm.cn/viewnews.php?id=1023 【题目描述】 给你一个长度为 n 的序列,序列中的元素只包括 1 和 -1。 请问有多少个连续的子序列乘积为正数。 【输入格式】 输入第一行为正整数 n。(n不超过10^6) 第二行包含 n 个整数。 【输

    2024年02月11日
    浏览(52)
  • 罗勇军 →《算法竞赛·快冲300题》每日一题:“小球配对” ← 并查集

    【题目来源】 http://oj.ecustacm.cn/problem.php?id=1850 http://oj.ecustacm.cn/viewnews.php?id=1023 【题目描述】 给定 n 个小球,编号为 1-n ,给定 m 个篮子,编号为 1-m 。 每个球只允许放入样例给定的编号为 Ai 或者 Bi 的两个篮子中的 1 个。 每个球必须放入某个篮子。 如果篮子中球的数量为奇

    2024年02月11日
    浏览(40)
  • 罗勇军 →《算法竞赛·快冲300题》每日一题:“游泳” ← DFS+剪枝

    【题目来源】 http://oj.ecustacm.cn/problem.php?id=1753 http://oj.ecustacm.cn/viewnews.php?id=1023 【题目描述】 游泳池可以等分为n行n列的小区域,每个区域的温度不同。 小明现在在要从游泳池的左上角(1, 1)游到右下角(n, n),小明只能向上下左右四个方向游,不能游出泳池。 而小明对温度十分

    2024年02月10日
    浏览(38)
  • 算法|每日一题|H 指数|二分

    原题地址: 力扣每日一题:H 指数 给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且每

    2024年02月08日
    浏览(42)
  • 每日一题之常见的排序算法

    排序是最常用的算法,常见的排序算法有冒泡排序、选择排序、插入排序、快速排序、希尔排序和归并排序。除此之外,还有桶排序、堆排序、基数排序和计数排序。 1、冒泡排序 冒泡排序就是把小的元素往前放或大的元素往后放,比较的是相邻的两个元素。 时间复杂度:

    2024年02月13日
    浏览(42)
  • 算法每日一题:赎金信 | 字符和整数

    hello,大家好,我是星恒 今天给大家带来的题目是一道简单题目,主要帮大家复习一下字符串和字符的相关操作 给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransom

    2024年01月21日
    浏览(44)
  • 【迎战蓝桥】 算法·每日一题(详解+多解)-- day5

    🤞目录🤞 💖1. 数组中出现次数超过一半的数字 💖2. 二进制中1的个数 💖3. 替换空格 【大家好,我是 爱干饭的猿 ,如果喜欢这篇文章, 点个赞 👍, 关注一下吧, 后续会一直分享题目与算法思路 】 描述 给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长

    2023年04月08日
    浏览(40)
  • 算法每日一题: 分割数组的最大值 | 动归 | 分割数组 | 贪心+二分

    Hello,大家好,我是星恒 呜呜呜,今天给大家带来的又是一道经典的动归难题。 题目:leetcode 410 给定一个非负整数数组 nums 和一个整数 k ,你需要将这个数组分成 k_ 个非空的连续子数组。 设计一个算法使得这 k _个子数组各自和的最大值最小。 示例: 示例 1: 示例 2: 示例

    2024年01月22日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包