172、木棒切割问题

https://sunnywhy.com/problem/172

题目描述

给出n根木棒的长度,现在希望通过切割它们来得到至少k段长度相等的木棒(长度必须是整数),问这些长度相等的木棒的最大长度。

输入描述

第一行为两个正整数n、k(1≤n≤103、1≤k≤108),分别表示木棒的根数、需要得到的长度相等的木棒根数;

第二行为n个整数(1≤每个整数≤105),表示木棒的长度。

输出描述

一个整数,表示木棒的最大长度。如果无法达成,此时最大长度为0

思考

如果通过暴力解法,那么复杂度为\(O(n^2)\)。每轮选择一个长度遍历每根绳子。

已知木棒分割的长度为正整数,且位于\([1,max(每根绳子的长度)]\)区间。当前为有序序列。求解至少k段长度相等木棒时,木棒的最大长度。

有序序列+求第一个满足某条件的元素的位置 => 二分法

已知木棒分割的长度序列从小到大,那么每个木棒长度对应的木棒段数序列从大到小

那么求木棒的最大长度,实际上在求最后一个 >= k 的木棒段数此时的木棒长度 。

但二分法是求第一个满足某条件的元素位置,为什么呢?不妨先试着编写求最后一个满足某条件元素位置的二分法。

假定序列从小到大排列,可以很容易写出下面三种情况。但在测试过程中,往往会出现死循环或没有输出的现象。

第1、3种情况无论如何也会让 \(left < right\) 不成立从而退出\(while\)循环。

那么很可能在第2种情况的时候陷入了死循环,求解一下死循环成立的条件。

\(\frac{left+right}{2} = left \\ \frac{right}{2} = \frac{left}{2} \\ \text 这是C语言的整除\)

二分法求解给定的\(while\)条件是\(left < right\)。显而易见,当left、right为相邻的奇偶时,且当 \(A[mid] == x\) 时,会无限死循环,每轮都会进入第2种情况。

所以牢记二分法用于寻找有序序列第一个满足某条件的元素的位置。

题解很简单,我们只需要求第一个分段数小于k的木棒长度然后减1即可。

解法

// https://sunnywhy.com/problem/172

// 考察二分查找

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio> int countSticks(int ans[], int len, int sep) {
int total = 0;
for (int i = 0; i < len; i++) {
total += ans[i] / sep;
}
return total;
} int main() {
int n, k, ans[1010], max = 0;
// 加载数据
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) {
scanf("%d", &ans[i]);
if (ans[i] > max) {
max = ans[i];
}
}
// 逻辑处理
int mid, left = 1, right = max;
while (left < right) {
mid = (left + right) / 2;
if (countSticks(ans, n, mid) < k) {
right = mid;
} else {
left = mid + 1;
}
};
printf("%d\n", --left); return 0;
}

二分法固定模板

C++算法之旅、02 从木棒切割问题领悟二分法精髓的更多相关文章

  1. HDU 5984(求木棒切割期望 数学)

    题意是给定一长为 L 的木棒,每次任意切去一部分直到剩余部分的长度不超过 D,求切割次数的期望. 若木棒初始长度不超过 D,则期望是 0.000000: 设切割长度为 X 的木棒切割次数的期望是 F( ...

  2. LeetCode初级算法--设计问题02:最小栈

    LeetCode初级算法--设计问题02:最小栈 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...

  3. Paxos算法之旅(四)zookeeper代码解析--转载

    ZooKeeper是近期比较热门的一个类Paxos实现.也是一个逐渐得到广泛应用的开源的分布式锁服务实现.被认为是Chubby的开源版,虽然具体实现有很多差异.ZooKeeper概要的介绍可以看官方文 ...

  4. js算法初窥02(排序算法02-归并、快速以及堆排序)

    上一篇,我们讲述了一些简单的排序算法,其实说到底,在前端的职业生涯中,不涉及node.不涉及后台的情况下,我目前还真的没想到有哪些地方可以用到这些数据结构和算法,但是我在前面的文章也说过了.或许你用不 ...

  5. 算法之旅,直奔<algorithm>之十七 find_first_of

    find_first_of(vs2010) 引言 这是我学习总结 <algorithm>的第十七篇,find_first_of是匹配的一个函数.<algorithm>是c++的 ...

  6. 算法之旅,直奔<algorithm>之十三 fill

    fill(vs2010) 引言 这是我学习总结<algorithm>的第十三篇,fill是一个很好的初始化工具.大学挺好,好好珍惜... 作用 fill  的作用是 给容器里一个指定的范围 ...

  7. 算法之旅,直奔<algorithm>之十四 fill_n

    fill_n(vs2010) 引言 这是我学习总结<algorithm>的第十四篇,作为fill的亲兄弟,fill_n也会助你一把的. 作用 fill_n 的作用是给一段指定长度的数据向量 ...

  8. 算法之旅,直奔<algorithm>之十五 find

    find(vs2010) 引言 这是我学习总结 <algorithm>的第十五篇.关于<algorithm>,每篇都很小,但是都很好用,可以秀出你的个性. 作用 find的作用 ...

  9. 算法之旅,直奔<algorithm>之十 count_if

    count_if(vs2010) 引言 这是我学习总结<algorithm>的第十篇,这个重要的地方是设置条件.用的还是蛮多的.(今天下午挺恶心的,一下午就做一个面试题,调代码调傻了... ...

随机推荐

  1. Luogu4391 [BOI2009]Radio Transmission 无线传输 (KMP)

    \(最小循环节\) \(=\) \(lenghth - next[lenghth]\) #include <iostream> #include <cstdio> #inclu ...

  2. java学习第七天xml.day18

    反射 在java中,反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力. 获取字节码的方式: 使用反射获取构造器 : 内省

  3. 手把手教你怎么将linux的一个函数性能搞奔溃

    static struct fib_table *fib_empty_table(struct net *net){    u32 id;    for (id = 1; id <= RT_TA ...

  4. 如何使用.NET 6的IHostedService和BackgroundService?

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 本章是<定制ASP NET 6.0框架系列文章>的第七篇.本文内容和定 ...

  5. java数组---初始化

    public class ArrayDemo { public static void main(String[] args) { int[] a={1,2,3,4,5,6,7,8,9}; //静态初 ...

  6. 字节一面:说说TCP的三次握手

    上周有朋友去了字节面试,问到了TCP三次握手的问题,当时回答的不是很好,对于三次握手的发送的报文信息都不太熟,本文主要做一下总结和记录. TCP全称为Transmission Control Prot ...

  7. NSK DD马达 直驱电机 RS232通信连接

    NSK DD马达 通信连接 通信测试平台 驱动器:NSK EDC系列 电机:NSK PS1006KN系列 电机线:UVW对应红白黑. 电源线:Main和Ctrl电路220V交流电供电即可. 测试软件: ...

  8. 全志H616基于官方外设开发-蜂鸣器

    #include <stdio.h> #include <wiringPi.h> #include <unistd.h> #define BEEP 0 //设置针脚 ...

  9. 通过vNode实现给列表字段打标签

    问题 如何给列表数据打标签?类似下面这种样子 思路 数模转化(对接口请求回来的数据进行过滤标记,返回新的数据) 渲染新的数据模型 实现 1.过滤数据,需要打标签的采用jsx写法 业务数据的处理我封装在 ...

  10. Beats:如何使用Winlogbeat