我们有n根的木棍。现在从这些木棍中切割出来m条长度相同的木棍,问这m根木棍最长有多长?
输入数据- 第一行输入两个数字,n和m
n(1<=n<=1000)为木棍数目
m(1<=m<=1000)为需要切割出的相同长度的木棍数目 - 随后n个正整数,表示原始木棍的长度(<=10000)
每组输出一行结果,表示切割后绳子的最长长度(保留两位小数)
样例输入4 5 5 6 7 8样例输出
4.00初始思路
- 因为要求切割的最大长度,本来想着从木棍长度中找到最大的长度,不断递减向下寻找,直到能切割的数目>= m。!不过不可以,因为切割的长度极有可能不为整数。
- 明确切割木棍的长度最粗略的范围就是0到当前木棍中最长的那个
- 明确范围之后,我们就可以使用二分查找了
- 每一次查找要计算 以当前mid指向的长度 切割的 木棍数目num
- 若num 大于等于m(想要的数目) 说明木棍长度小了 所以要更新left为mid
- 反之 更新 right 为mid
- 直到left 等于right时,就找到了满足当前条件的最长的切割长度了
#include补充#include #include #include #include //round四舍五入 using namespace std; int main() { int n, m; vector lens; cin >> n >> m; for (int i = 0; i < n; i++) { int temp; cin >> temp; lens.push_back(temp); } auto max = max_element(lens.begin(), lens.end()); //max_element 返回的是迭代器 double l = 0, r = *max; //能切割的木棒长度 最粗略的范围就是0到当前木棒中最大的 double mid; while (l + 0.01 < r) //不断更新范围 直到 l = r = 最佳解 { int num = 0; mid = round(((l + r) / 2.00) * 100) / 100.00; //保证精度 // float middd = round(l + r) / 2.00; //不可以 (4+4.5)=4.5 for (int i = 0; i < n; i++) num += (int)(lens[i] / mid); //针对当前长度 看每个lens能切割成多少个 if (num >= m) //当前的切割 得到的木棍多 说明当前的切割长度小了 l = mid; else r = mid; } printf("%.2f", l); system("pause"); return 0; }
- mid = round(((l + r) / 2.00) * 100) / 100.00; 为了保证精度到小数点后两位
- num += (int)(lens[i] / mid); 因为木棍切割只能向下取整,所以int的除法刚好合适
- max_element() 返回容器中最大值的迭代器,所以输出值的话要对其取 *
- 对于格式化的输入和输出,scanf 和 printf更方便
- 若文章存在问题,还请各位大佬批评指正,共同进步。



