绳子切割问题:给出N条绳子的长度,问按照一定长度 LG 切割这几条绳子得到至少 k 条肠胃 LG 的绳子,问长度L最长为多少,保留2位小数。
方法1:
枚举法:绳子从0.01米开始增加,每次增加 0.01 米,直到 L[i] / LG之和小于k,则此时的LG - 0.01就是题目要求的答案:
代码为:
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int N;
int k;
double L[10];
scanf("%d%d", &N, &k);
for(int i = 0; i < N; i++)
scanf("%lf", &L[i]);
double LG;
for(LG = 0.01; ;LG++)
{
int num = 0;
for(int i = 0; i < N; i++)
{
num += (int)(L[i] / LG);
}
if(k > num)
break;
}
printf("%.2f\n", LG - 0.01);
return 0;
}
输入与运行结果为:
4 11
8.02 7.43 4.57 5.39
2.00
方法2:
二分法,其实也比较简单,但是实际上写起来比较麻烦,LG下届是保证>= k,所以最终一定是LG输出,输出UG则为2.01。
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int N;
int k;
double L[10];
scanf("%d%d", &N, &k);
for(int i = 0; i < N; i++)
scanf("%lf", &L[i]);
double LG, UG;
LG = 0.01;
UG = 10.00;
double mid;
while(UG - LG > 0.01)
{
mid = (UG + LG) / 2;
int num = 0;
for(int i = 0; i < N; i++)
{
num += (int)(L[i] / mid);
}
if(num < k)
UG = mid - 0.01;
else
LG = mid;
}
printf("%.2f\n", LG);
return 0;
}