Cable master(浮点数二分)

本文介绍了一种通过二分查找算法确定从现有电缆中切割指定数量的最大长度线段的方法,用于解决编程竞赛中网络布线的问题。文章详细解释了算法实现过程及注意事项。

Description
Inhabitants of the Wonderland have decided to hold a regional programming contest. The Judging Committee has volunteered and has promised to organize the most honest contest ever. It was decided to connect computers for the contestants using a “star” topology - i.e. connect them all to a single central hub. To organize a truly honest contest, the Head of the Judging Committee has decreed to place all contestants evenly around the hub on an equal distance from it.
To buy network cables, the Judging Committee has contacted a local network solutions provider with a request to sell for them a specified number of cables with equal lengths. The Judging Committee wants the cables to be as long as possible to sit contestants as far from each other as possible.
The Cable Master of the company was assigned to the task. He knows the length of each cable in the stock up to a centimeter,and he can cut them with a centimeter precision being told the length of the pieces he must cut. However, this time, the length is not known and the Cable Master is completely puzzled.
You are to help the Cable Master, by writing a program that will determine the maximal possible length of a cable piece that can be cut from the cables in the stock, to get the specified number of pieces.
Input
The first line of the input file contains two integer numb ers N and K, separated by a space. N (1 = N = 10000) is the number of cables in the stock, and K (1 = K = 10000) is the number of requested pieces. The first line is followed by N lines with one number per line, that specify the length of each cable in the stock in meters. All cables are at least 1 meter and at most 100 kilometers in length. All lengths in the input file are written with a centimeter precision, with exactly two digits after a decimal point.
Output
Write to the output file the maximal length (in meters) of the pieces that Cable Master may cut from the cables in the stock to get the requested number of pieces. The number must be written with a centimeter precision, with exactly two digits after a decimal point.
If it is not possible to cut the requested number of pieces each one being at least one centimeter long, then the output file must contain the single number “0.00” (without quotes).
Sample Input
4 11
8.02
7.43
4.57
5.39
Sample Output
2.00

一堆绳子,剪成长度为x的绳子,要求剪出至少k条这样的绳子,问x最大是多少。

直接二分就好了,二分判断就是每个绳子除以mid,然后求和,如果大于等于k,那就OK,否则false。
这里是浮点数二分,精度比较坑,有人说加0。06就行- -,太玄幻了,没用,用了floor……浮点数精度一直是个坑啊。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<utility>
#include<sstream>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1005;
int n,k;
double a[10005];
bool check(double temp)
{
    int ans = 0;
    for(int i = 1;i <= n;i++)
        ans = ans + (int)(a[i]/temp);
    if(ans >= k)return true;
    else return false;
}
int main()
{
    #ifdef LOCAL
    freopen("C:\\Users\\巍巍\\Desktop\\in.txt","r",stdin);
    //freopen("C:\\Users\\巍巍\\Desktop\\out.txt","w",stdout);
    #endif // LOCAL
    scanf("%d%d",&n,&k);
    for(int i = 1;i <= n;i++)
        scanf("%lf",&a[i]);
    double l,r;
    l = 0;r = 100000000;
    for(int i = 1;i <= 100;i++)
    {
        double mid = (l + r)/2;
        if(check(mid))
            l = mid;
        else
            r = mid;
    }
    printf("%.2lf\n",floor(r*100)/100);
    return 0;
}
<think>好的,用户想了解浮点数二分法的实现和原理。首先,我需要回忆一下相关的知识点,尤其是和整数二分的区别。根据用户提供的引用,浮点数二分不需要处理边界问题,因为除法结果是浮点数,不需要像整数那样考虑加一减一。 首先,我应该先解释浮点数二分的基本原理,比如终止条件和循环条件。用户提供的引用中提到,浮点数二分通过不断缩小区间来逼近解,直到区间足够小。比如,当区间长度小于某个极小值eps时终止循环。这一点需要详细说明,因为这是浮点数二分的关键。 然后,需要给出一个具体的例子或者代码示例,帮助用户理解。比如,可以引用例题中的平方根计算,说明如何用浮点数二分来求解。同时,代码示例应该用Python或者其他用户熟悉的语言,但根据用户提供的示例,可能更倾向于Python。不过引用中的例题来自acwing,可能需要参考他们的实现方式。 接下来,要对比浮点数二分和整数二分的不同。根据引用[1],浮点数二分不需要处理边界,所以不需要考虑mid+1或mid-1,循环条件也不同。这里需要明确说明两者的差异,比如循环终止条件和变量更新方式。 还要注意浮点数二分的精度问题,即如何选择合适的eps。引用[3]可能提到这一点,需要说明根据题目要求确定精度,通常比题目要求的精度再小两个数量级,避免误差。例如,如果题目要求保留6位小数,eps可以设为1e-8。 然后,用户可能关心实现步骤,所以分步骤解释:确定初始区间、循环终止条件、中间值计算、区间更新。每一步都要结合浮点数的特点,比如初始区间可能需要根据问题调整,比如平方根的话,右端点可以取x本身或者更大。 在代码实现部分,需要确保使用正确的格式,比如用户要求行内数学表达式用$...$,独立公式用$$...$$。例如,计算x的平方根时,循环条件是r - l > eps,中间值mid = (l + r)/2,然后根据mid的平方与x的比较更新区间。 此外,引用[4]提到位运算不适用于浮点数,所以计算mid时直接使用(l + r)/2,而不是位运算。这一点需要强调,避免用户混淆。 可能还需要提到应用场景,比如求解方程根、优化问题等,这些引用中的内容可能涉及。例如,acwing的例题可能涉及数的范围,但浮点数二分用于连续问题。 最后,生成相关问题时要围绕浮点数二分的实现细节、精度选择、与整数二分的区别、应用场景等。确保问题覆盖用户可能进一步想了解的内容。 现在,整理这些思路,按照用户的结构要求:先回答,再相关问题,使用正确的中文和格式,确保引用正确。需要引用时,根据用户提供的四个引用,适当添加引用标识。例如,当提到不需要处理边界时引用[^1],提到精度时引用[^3]等。</think>### 浮点数二分法的实现与原理 浮点数二分法用于在**连续区间**中寻找满足条件的数值解,其核心思想是通过不断缩小区间范围逼近目标值。与整数二分不同,浮点数二分无需处理边界问题,且通过设置精度阈值(如$10^{-6}$)控制终止条件。 #### 一、实现原理 1. **终止条件**:当区间长度小于预设精度$\epsilon$时停止循环,例如: $$ |r - l| < \epsilon $$ 其中$\epsilon$通常取题目要求精度的$1/100$,例如要求保留4位小数时$\epsilon=10^{-6}$。 2. **中间值计算**:直接取区间中点,无需位运算: $$ mid = \frac{l + r}{2} $$ (注意:浮点数不能使用`l + r >> 1`,此为整数二分专用[^4]) 3. **区间更新**:根据条件判断缩小区间。例如,求$x$的平方根时: - 若$mid^2 > x$,说明解在左半区间,更新$r = mid$ - 若$mid^2 \leq x$,说明解在右半区间,更新$l = mid$ #### 二、代码示例(Python) ```python def sqrt_bisection(x, eps=1e-6): l, r = 0, max(1, x) # 初始区间根据问题调整 while r - l > eps: mid = (l + r) / 2 if mid * mid > x: r = mid else: l = mid return l ``` #### 三、与整数二分的对比 | **特征** | 浮点数二分 | 整数二分 | |----------------|---------------------------|---------------------------| | 循环条件 | `while r - l > eps` | `while l < r` | | 中间值计算 | `(l + r)/2` | `(l + r) >> 1`或`mid+1` | | 边界更新 | 直接赋值`l=mid`或`r=mid` | 需处理`mid+1`或`mid-1`| #### 四、典型应用场景 1. 求解方程根(如$x^3 + 2x - 5 = 0$) 2. 计算几何问题(如凸优化) 3. 机器学习中的参数搜索(如学习率调整)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值