洛谷 P1577 切绳子 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P1577 切绳子 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:

题目描述

有N条绳子,它们的长度分别为Li。如果从它们中切割出K条长度相同的

绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位。

输入输出格式

输入格式:

第一行两个整数N和K,接下来N行,描述了每条绳子的长度Li。

输出格式:

切割后每条绳子的最大长度。

输入输出样例

输入样例#1:
4 11
8.02
7.43
4.57
5.39
输出样例#1:
2.00

说明

对于100%的数据 0<Li<=100000.00 0<n<=10000 0<k<=10000

 

分析:

一开始没想到什么好办法,精度0.001直接二分,精彩地WA了7个点...

之后又把精度加到0.0001,并没啥用

然后发现“好像二分计算整数更合适吧”

emmmmmm....

 

47分代码:

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm> 
 6 
 7 const int MAXN = 10005;
 8 
 9 inline void read(int &x)
10 {
11     x = 0;char ch = getchar(), c = ch;
12     while(ch < 0 || ch > 9)c = ch, ch = getchar();
13     while(ch <= 9 && ch >= 0)x = x * 10 + ch - 0, ch = getchar();
14     if(c == -)x = -x;
15 }
16 
17 int n,k;
18 double l,r,mid,ans,num[MAXN],tmp[MAXN];
19 
20 int cmp(int a,int b)
21 {return a>b;}
22 
23 void update()
24 {
25     for(int i = 1;i <= n;++ i)
26         tmp[i] = num[i];
27 }
28 
29 bool jud(double x)
30 {
31     int tot = 0;
32     update();
33     for(int i = 1;i <= n;++ i)
34     {
35         if(tot >= k) return true;
36         while(tmp[i]-x >=0) tot ++,tmp[i]-=x;
37     }
38     if(tot >= k) return true;
39     return false;
40 }
41 
42 int main()
43 {
44     read(n),read(k);
45     for(int i = 1;i <= n;++ i)
46         scanf("%lf",&num[i]);
47     std::sort(num+1,num+1+n,cmp);
48     l = 0,r = num[n];
49     while(l <= r)
50     {
51         mid = (l+r)/2.0;
52         if(jud(mid)) ans = mid,l = mid+0.0001;
53         else r = mid-0.0001;
54     }
55     printf("%.2lf",ans);
56     return 0;
57 }
1.6.9.10.11.12.AC

 

AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm> 

const int MAXN = 10005;

inline void read(long long &x)
{
    x = 0;char ch = getchar(), c = ch;
    while(ch < 0 || ch > 9)c = ch, ch = getchar();
    while(ch <= 9 && ch >= 0)x = x * 10 + ch - 0, ch = getchar();
    if(c == -)x = -x;
}

long long n,k,l,r,mid,ans,num[MAXN],tmp[MAXN];
double a;

int cmp(long long a,long long b)
{return a>b;}

void update()
{
    for(int i = 1;i <= n;++ i)
        tmp[i] = num[i];
}

bool jud(long long x)
{
    int tot = 0;
    update();
    for(int i = 1;i <= n;++ i)
    {
        if(tot >= k) return true;
        if(num[i] < x || !x) break;
        tot += num[i]/x;
    }
    if(tot >= k) return true;
    return false;
}

int main()
{
    read(n),read(k);
    for(int i = 1;i <= n;++ i)
        scanf("%lf",&a),num[i] = a*100;
    std::sort(num+1,num+1+n,cmp);
    l = 0,r = num[1];
    while(l <= r)
    {
        mid = (l+r)>>1;
        if(jud(mid)) ans = mid,l = mid+1;
        else r = mid-1;
    }
    printf("%.2lf",(double)ans/100.0);
    return 0;
}

 

以上是关于洛谷 P1577 切绳子 题解的主要内容,如果未能解决你的问题,请参考以下文章

P1577 切绳子

P1577 切绳子

luogu P1577 切绳子

P1577 切绳子

P1577 切绳子(二分)

洛谷1577 1297切绳子(二分答案)