题目:
这题有点坑,G++过不了,C++能过。
条件:n个数据a[],分成k段,结果精度要求两位小数。
问题:每段最长为多少?
思路:因为精度要求为两位小数,我先把所有的长度a[]*100。
我们对答案二分搜索,把l设置为0,r设置为1000*10000*100+1(数据量*每个数据最大的大小*精度+1)。
这样我们搜索的数就不用处理精度了,我们可以二分算出结果然后除以100。
代码:
#include <iostream> #include <algorithm> #include <map> #include <vector> #include <set> #include <math.h> #include <queue> #include <assert.h> #include <stdio.h> #include <stdlib.h> using namespace std; typedef long long ll; #define INF 2147483647 //输入 int n, k; double a[10010]; //返回分成k段最大的段长 double solve(ll sum) { ll l = 0, r = sum+1; //二分的左右端 ll mx = 0; //保存结果 while (l < r) { ll mid = (l + r) / 2; ll sum = 0; //段数求和 for (int i = 0; i < n; i++) sum += a[i] / mid; //每段长mid,可以分成k段 if (sum >= k) { mx = max(mx, mid); //更新答案 l = mid + 1; } else { r = mid; } } return 1.0*mx/100; } int main() { cin >> n >> k; ll sum = 0; for (int i = 0; i < n; i++) { cin >> a[i]; a[i] *= 100; //将段长乘以100 sum += a[i]; //对段长求和 } printf("%.2lf",solve(sum)); getchar(); getchar(); return 0; }