洛谷 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 }
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 切绳子 题解的主要内容,如果未能解决你的问题,请参考以下文章