关于二分精度问题
例题: cf782B
提议:在数轴x上给n个点的位置,每个点都有一个最大的移动速度,方向任意。在数轴x上找一个点c,使得这n个点到点c的最大时间最小,输出最小时间,误差 <= 0.000001。
思路:定义L = 0, R= Max, 二分点c的位置,然后对于每个位置,check一下;
初解:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
const int MAXN = 6e4 + 5;
const double Min = 0.0000001;
double s[MAXN + 5], v[MAXN + 5];
int n;
int check(double ans)
{
double Max_L = 0, Max_R = 0;
for(int i = 1; i <= n; i++){
if(s[i] > ans){
double x = (s[i] - ans) / v[i];
Max_R = max(Max_R, x);
}
else if(s[i] < ans){
double x = (ans - s[i]) / v[i];
Max_L = max(Max_L, x);
}
}
if(Max_R > Max_L) return 1;
return 0;
}
void find(double L, double R)
{
while(R - L >= Min){ //当R - L >= Min即进行二分,结果T在了test21, 正解是强行二分100次(即在考虑精度的二分题目中尽量用强制二分n次来保证精度)
double mid = (R + L) / 2;
int k = check(mid);
if(k == 1) L = mid;
else R = mid;
sum++;
}
double Max = 0;
for(int i = 1; i <= n; i++){
if(s[i] > L){
double x = (s[i] - L) / v[i];
Max = max(Max, x);
}
else{
double x = (L - s[i]) / v[i];
Max = max(x, Max);
}
}
printf("%lf\n", Max);
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%lf", &s[i]);
for(int i = 1; i <= n; i++) scanf("%lf", &v[i]);
double L = 1, R = 1000000000;
find(L, R);
}

浙公网安备 33010602011771号