poj 1064 二分查找变形—判定并找到可行解

题目来源: poj 1064 Cable master

题目概述:有N条绳子,他们的长度分别为Li,如果从它们中切割出k条长度相同的绳子的话,这K条绳子每条能有多长?

思路:使用二分法,判断最大值的范围,有三种情况:

  • 当前剪的总数 小于 题目要求的K条,这时候我们确定,当前的区间范围来说,右边界过大,导致中间值middle过大,所以要将右边界=middle_value。
  • 当前剪的总数相等题目要求的k条,这时候我们确定,当前的区间范围来说,middle正处于合适的范围区间,但是middle的取值是不是最大值呢,需要middle的数值扩大,所以将左边界扩大,左边界 = middle_value.
  • 当前剪得的总数大于题目要求的k条,这时候我们确定,当前区间范围来说,middle的取值满足要求,但是是否是最大值,还是需要重新确认边界,所以左边界=middle,在此扩大middle的取值

注意:因为此时左边界(left_value),右边界(right_value),中间值(middle_value)都是浮点数,所以判断区间的时候会有两种方法:

  • 左边界 - 右边界 > 一个足够小的数值,一般都设置为1e-5
  • 一种是循环到合适的数值,一般来说,循环一百次,相当于达到了10的-30次方的精度,也是足够的


#include<iostream>
#include<stdio.h>
#include<math.h>
#define INF 9999999;
using namespace std;

bool pd_section (double middle, double* dataSet, int K, int N){
    int num = 0;
    for (int i=0; i<N; i++){
        num += (int)(dataSet[i] / middle);
    }
    bool result = num >= K ? true : false;
    return result;
}

int main () {
    int N,K;
    double dataSet[10001];
    while (cin>>N>>K){
        for (int i=0; i<N; i++){
            cin>>dataSet[i];
        }
        double start_flag, end_flag;
        start_flag = 0;
        end_flag = INF;
        for (int i=0; i<=100; i++){
            double middle_flag = (start_flag + end_flag) / 2;
            if ( pd_section(middle_flag, dataSet, K, N)){
                start_flag = middle_flag;
            } else {
                end_flag = middle_flag;
            }
        }
        printf("%.2lf\n", floor(end_flag * 100) / 100);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值