首页 > 编程语言 >信息学奥赛初赛天天练-69-NOIP2017普及组-完善程序2-切割绳子、二分答案、二分边界、二分边界、二分时间复杂度

信息学奥赛初赛天天练-69-NOIP2017普及组-完善程序2-切割绳子、二分答案、二分边界、二分边界、二分时间复杂度

时间:2024-08-19 18:38:08浏览次数:7  
标签:二分 边界 mid 初赛 棍子 长度 处应 left

1 完善程序 (单选题 ,每小题3分,共30分)

切割绳子

有 n 条绳子,每条绳子的长度已知且均为正整数。绳子可以以任意正整数长度切割,但不可以连接。现在要从这些绳子中切割出 m条长度相同的绳段,求绳段的最大长度是多少。(第一、二空 2.5 分,其余 3分)

输入:第一行是一个不超过 100的正整数 n,第二行是 n个不超过 10^6的正整数,表示每条绳子的长度,第三行是一个不超过 10^8的正整数 m。

输出:绳段的最大长度,若无法切割,输出 Failed

01 #include<iostream>
02 using namespace std;
03 int n, m, i, lbound, ubound, mid, count;
04 int len[100]; // 绳子长度
05 int main()
06 {
07     cin >> n;
08     count = 0;
09     for (i = 0; i < n; i++)
10     {
11         cin >> len[i];
12         ①;
13     }
14     cin >> m;
15     if (②)
16     {
17         cout << "Failed" << endl;
18         return 0;
19     }
20     lbound = 1;
21     ubound = 1000000;
22     while (③)
23     {
24         mid = ④;
25         count = 0;
26         for (i = 0; i < n; i++)
27             ⑤;
28         if (count < m)
29             ubound = mid - 1;
30         else
31             lbound = mid;
32     }
33     cout << lbound << endl;
34     return 0;
35 }

1 ①处应填( )

2 ②处应填( )

3 ③处应填( )

4 ④处应填( )

5 ⑤处应填( )

2 相关知识点

二分答案

二分答案顾名思义,它用二分的方法枚举答案,并且枚举时判断这个答案是否可行

直接对答案进行枚举查找,接着判断答案是否合法。如果合法,就将答案二分进一步靠近,如果不合法,就接着二分缩小判断。这样就可以大大的减少时间。

二分中有时可以得可行得答案,但不是最大的,继续向右靠近,求出最大值

 int ans = 1;
 int l = 1,r = 100000;//在1~100000之间的整数枚举 
 while(l <= r){
     int m = l + (r - l) / 2;
     if(check(m)){//满足 则进行向右缩小范围 看看有没有更大的 
         ans = m;//可能多次赋值 最后一定是可能的最大值 
         l = m + 1;
      }else{//不满足缩小边长 向左缩小范围 用更小边长继续尝试 
         r = m - 1;
	  } 
  }

二分查找中间值

/* 向右逼近,如果找到满足条件的数,会继续向右找更大的数,让循环结束
   mid=(left+right)/2 left和right都接近最大值时,可能溢出可以使用下面写法替换
   mid=left + (right-left) / 2;
   可以求满足条件的最大值
*/
    
/* 向左逼近,如果找到满足条件的数,会继续向左找更小的数,让循环结束
   mid=(left+right+1)/2 left和right都接近最大值时,可能溢出可以使用下面写法替换
   mid=left + (right-left+1) / 2;
   可以求满足条件的最小值
*/

二分找边界

//左闭右闭 while left right 最终left=right+1
while(left<=right)  left = mid + 1; right =mid-1;
//左闭右开 while left right 最终left=right
while(left<right)   left = mid + 1; right =mid;
//左开右闭 while left right 最终left=right
while(left<right)   left=mid;       right=mid-1;
//左开右开 while left right 最终left=right-1
while(left+1<right) left=mid;       right=mid;

二分查找时间复杂度

二分查找每次都缩小或扩大为原来的一半,所以也是Olog(n)

3 思路分析

每个棍子长度不超过10^6,且棍子切割必须为整数,因此通过二分的方法在1~ 10^6之间寻找答案

找到1个可能的棍子的长度后,计算n个棍子可以切分棍子的总数

如果总数<m,则切分不够,继续缩小棍子的长度,来切分更多的棍子

直到切分的长度大于等于m

例如

输入
3
4 6 12
7
范围缩小到 lbound=1,ubound=10时
此时mid=(1+10+1)/2=6,使用长度为6进行切分时,3个棍子分别切分为0+1+2=3不能满足m=7

ubound=mid-1=6-1=5
此时mid=(1+5+1)/2=3,使用长度为3进行切分时,3个棍子分别切分为1+2+4=7满足m=7

1 ①处应填( count=count+len[i] )

分析

考虑一种情况,先把棍子长度加起来,如果切成最小单位,每个棍子长度为1
这些棍子的总数比m还小,则无法切割
count=count+len[i] 可以看作把所有最小长度为1的棍子都加起来

2 ②处应填( count<m )

分析

考虑一种情况,先把棍子长度加起来,如果切成最小单位,每个棍子长度为1
这些棍子的总数比m还小,则无法切割
count 可以看作把所有最小长度为1的棍子都加起来,如果还不到m个棍子,则无法切割

3 ③处应填( lbound<ubound )

分析

根据如下二分找边界可知, lbound<ubound
//左开右闭 while left right 最终left=right
while(left<right)   left=mid;       right=mid-1;

4 ④处应填( (lbound+ubound+1)/2 )

分析

根据如下二分找中间值可知, 当特殊情况左边界值不会增加, (lbound+ubound)/2的值不变,会进入死循环
 (lbound+ubound)/2会使得左边界+1,结束循环
28         if (count < m)
29             ubound = mid - 1;
30         else
31             lbound = mid;

5 ⑤处应填( count+=len[i]/mid )

分析

二分找出一个棍子长度mid,计算所有棍子,按mid长度可以切分的棍子数量
26         for (i = 0; i < n; i++)
27             ⑤;

标签:二分,边界,mid,初赛,棍子,长度,处应,left
From: https://www.cnblogs.com/myeln/p/18367887

相关文章

  • wqs 二分
    感觉是一个很神秘的东西。例题P2619[国家集训队]TreeI从\(m\)条边中选\(n-1\)条要求选恰好\(k\)条白边,且边集是原图生成树求边权和的最小值这题不算是dp,但还是记\(f_i\)为恰好选\(i\)条白边的最小代价。而wqs二分的要求是函数要具有凸性。简单版本就是选......
  • Pico程序设置安全边界(不想每次手动设置)
     ///<summary>///安全设置路径///</summary>privatestring_configSavePath="/storage/emulated/0/Android/data/com.pvr.seethrough.setting/files/config1.txt";privatevoidSetBoundary(){if(!File.Exists(_configSavePath))......
  • 【C++二分查找】1954. 收集足够苹果的最小花园周长
    本文涉及的基础知识点C++二分查找LeetCode1954.收集足够苹果的最小花园周长给你一个用无限二维网格表示的花园,每一个整数坐标处都有一棵苹果树。整数坐标(i,j)处的苹果树有|i|+|j|个苹果。你将会买下正中心坐标是(0,0)的一块正方形土地,且每条边都与两条坐......
  • 二分 查找
    二分查找https://leetcode.cn/problems/binary-search/思路这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想......
  • 二分查找算法详解及Python实现
    目录引言二分查找算法步骤二分查找的Python实现性能分析注意事项引言二分查找算法(BinarySearch)是一种在有序数组中查找某一特定元素的搜索算法。它的基本思想是:通过比较数组中间的元素与目标值的大小,将搜索区间缩小为一半,直到找到目标值或搜索区间被缩小为0。二分查......
  • 8.17日二分测试总结
    8.17日二分测试总结比赛传送门分数情况A.砍树B.买木头C.数列分段2D.吃冰棍E.跳石头F.奶牛晒衣服10080100\(_{没做:(}\)100总体分数\(_{很惨}\)T1.P1873[COCI2011/2012#5]EKO/砍树题目传送门问题分析运用二分答案与check函数check函数......
  • D46 2-SAT+线段树优化+二分 [ARC069F] Flags
    视频链接: [ARC069F]Flags-洛谷|计算机科学教育新生态(luogu.com.cn)//D462-SAT+线段树优化+二分O(nlognlogv)#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;#definemid((l+r)>>1)#definels(u<<1)#definer......
  • P8844 [传智杯 #4 初赛] 小卡与落叶
    原题面:P8844[传智杯#4初赛]小卡与落叶大概题意:给你一棵有\(n(1\len\le10^5)\)个结点的有根树,根结点标号为\(1\),根节点的深度为\(1\),最开始整棵树的所有结点都是绿色的。小卡有\(m(1\lem\le10^5)\)个操作。操作一:把整棵树都染绿,之后让深度\(\gex\)的结点变......
  • 二分查找不理解?一篇弄懂!--基础二分查找算法详细解释(带简单例题的详细解法)
    本文参考:灵茶山艾府分享丨【题单】二分算法(二分答案/最小化最大值/最大化最小值/第K小)-力扣(LeetCode)二分查找红蓝染色法_哔哩哔哩_bilibili本文主要详细讲解基础的二分算法中的查找,包括原理和模板,并用leetcode和洛谷的一些例题来进行实际题目讲解,如果觉得有帮助或者写......
  • 二分查找(算法详解+模板+例题)
    一.二分的定义二分法(Bisectionmethod)即一分为二的方法.设[a,b]为R的闭区间.逐次二分法就是造出如下的区间序列([an,bn]):a0=a,b0=b,且对任一自然数n,[an+1,bn+1]或者等于[an,cn],或者等于[cn,bn],其中cn表示[an,bn]的中点。二.基本思路1.将数组排序。2.一直将数组除以二,直到找到那......