用二分法找到符合条件的最值
开始时用的绝对精度判断解的正确性,在大的test case上会tle,
后来用了相对精度,ac了
#include<iostream>#include<stdio.h>#include<string.h>#include<cstring>#include<string>#include<algorithm>#include<cstdlib>using namespace std;const int maxn = 1005;double n, len, d[maxn];double eps = 1e-9;bool valid(double v, int idx){
double edge = 0.0;
for(int i = 0; i < idx - 1;){
if(d[i] - v <= edge){
edge = max(edge,d[i] + v);
++i;
}
else{
return false;
}
}
if((d[idx - 1] - v <= edge) && (d[idx-1] + v >= len)){
return true;
}
return false;}bool isok(double test, double sta){
double bias = test - sta;
bias = bias < 0 ? -bias : bias;
double per = bias / sta;
return per < eps;}int main(){
cin >> n >> len;
for(int i = 0; i < n; ++i){
cin >> d[i];
}
sort(d, d + (int)n);
int idx = 0;
for(int i = 1; i < n; ++i){
if(d[i] != d[idx]){
d[++idx] = d[i];
}
}
++idx;
//cout << idx << endl;
double l = 0, r = len, best = len + 1;
for(int i = 1; i < idx; ++i){
double bias = d[i] - d[i-1];
if(l < bias){
l = bias;
}
if(r > bias){
r = bias;
}
}
l = (l + 1.0) / 2.0;
r = r / 2.0;
l = max(l, d[0]);
l = max(l, len - d[idx-1]);
r = min(r, d[0]);
r = min(r, len - d[idx-1]);
double ttt = r;
r = l;
l = ttt;
++r;
bool locate = false;
while(((r - l) >= eps)){
double mid = (l + r) / 2.0;
if(valid(mid, idx)){
// cout << mid << endl;
locate = true;
if(isok(best, mid)){
best = min(best,mid);
break;
}
best = min(best, mid);
r = mid;
}
else{
l = mid;
}
}
printf("%.9f\n", best);
return 0;}