1 我的错误代码 84 2 3 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cmath> 8 using namespace std ; 9 10 const int maxn = 10011 ; 11 const double eps = 1e-7 ; 12 int n,k ; 13 double a[maxn] ; 14 double sum,l,r,mid,t ; 15 16 inline double absss(double x) 17 { 18 if(x<0) return -x ; 19 return x ; 20 } 21 22 inline bool check(double mid) 23 { 24 int sum = 0 ; 25 for(int i=1;i<=n;i++) sum = sum + (int)( a[ i ] / mid +eps ) ; 26 return sum >= k ; 27 28 } 29 30 int main() 31 { 32 scanf("%d%d",&n,&k) ; 33 for(int i=1;i<=n;i++) 34 { 35 scanf("%lf",&a[ i ]) ; 36 sum+=a[ i ] ; 37 } 38 r = sum / k +0.11 ; 39 l = 0.001; 40 while(absss(r-l)>eps) 41 { 42 t++ ; 43 if(t>100) break ; 44 mid = (l+r) / 2 ; 45 if( check( mid ) ) 46 l = mid ; 47 else 48 r = mid - 0.001 ; // 49 } 50 printf("%.2lf",floor(l*100)/100+0.001 ) ; 51 return 0 ; 52 }
洛谷P1577 切绳子
二分答案 卡精度
我日 这道题 卡我精度
不爽 然后就直接抄题解了
来自洛谷的题解 :
那个实在不好意思,我之前贴成另一道题的代码了.
二分查找,设C(x)为=可以得到K条长度为x的绳子。
由于长度为L的绳子最多可以切出floor(L/x)段长度为x的绳子,因此C(x)=(floor(L/x)的总和是否大于等于K)由于1次循环可以缩小区间的一半,100次循环可以达到10^-30的精度,是绝对够了的。
正确代码如下(洛谷能否把错的题解帮我给删一下)
1 题解 2 3 4 #include<cstdio> 5 #include<algorithm> 6 #include<iostream> 7 #include<cmath> 8 using namespace std; 9 int k,n; 10 double l[10005]; 11 bool C(double x) 12 {int num=0; 13 for(int i=1;i<=n;i++) 14 num+=(int)(l[i]/x); 15 return num>=k; 16 } 17 int main() 18 { cin>>n>>k; 19 for(int i=1;i<=n;i++) 20 cin>>l[i]; 21 double lb=0,ub=0x7fffffff; 22 for(int i=1;i<=100;i++) 23 { 24 double mid=(lb+ub)/2; 25 if(C(mid)) lb=mid; 26 else ub=mid; 27 } 28 printf("%.2f\n",floor(ub*100)/100); 29 return 0; 30 }