洛谷 P1577 切绳子

原题传送门:切绳子 - 洛谷

 


一道简单的二分答案,但是却让我错了将近一页。 

 AC代码

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e4+1;

int n,k;
double L[MAXN],r,ans,l,mid;
char s[100];
bool canGetKCount(){
    int cnt=0;
    for(int i=1;i<=n;i++){
        cnt+=L[i]/mid;
    }
    return cnt>=k;
}

int main(){
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%lf",&L[i]);
        r+=L[i];
    }

    while(r-l>0.0001){
        mid=(l+r)/2;
        if(!canGetKCount()){//切不到k条,少切一点,切的更多
            r=mid;
        }else{
            l=mid;
        }
    }

    sprintf(s+1,"%.3f",l);
    s[strlen(s+1)]='\0';
    printf("%s",s+1);
/*93分代码
    l=(floor(l*100.0)/100.0);
    cout<<fixed<<setprecision(2)<<l<<endl;
*/
    return 0;
}

二分答案的重点是要明白,l,r,mid,都是什么含义,比如这道题输出的是l,其他题目可能就是r或者mid了。这里用while(r-l>0.0001)实际上是在刷精度,类似三分法。

同时上面是cnt>=k,而不是cnt==k,因为cnt>=k都是合理的解。

93分错的那一个点下载下来输出是对的,提交就是错的..

r只要取最大的那一条乘以2就可以保证mid从最大的情况开始割,但是多了这么多步骤实际上没必要,不如直接r=INT_MAX,反正二分的效率这么高。

同时这道题是要求舍弃小数点后两位,所以可以考虑运算的时候把所有数都乘100变成整数来用,输出的时候再除以100,0即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值