题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=4932

题目大意:

来自百度翻译
在X轴上有N个点。苗苗想用同样长度的片段来覆盖它们。
有两个限制:
1.如果有一个线段T,则该点是T的左端或右端。
2.任意两段相交的长度等于零。
例如,点2由[2,4]转换而不是由[1,3]转换。[1,2]和[2,3]是合法段,[1,2]和[3,4]是合法段,但[1,3]和[2,4]不是(相交长度不等于零),[1,3]和[3,4]不是(长度不同)。
苗苗想最大化分段长度,请告诉她最大分段长度。
据你所知,这一点不可能碰巧在同一位置。

解题思路

我的思路是二分区间长度判断是否可行,但是wa了。
正确思路:
枚举区间长度,区间长度不是两个相邻位置的差值就是差值的一半,这步是核心之一。
判断是否可行。
判断的时候还要注意一点:
存在一个区间覆盖两个点的情况,比如:-100 32 45 4 12 231

AC代码

#include<bits/stdc++.h>
#define ll long long
const int N=100;
const int inf=0x3f3f3f3f;
const double esp=1e-8;
using namespace std;
int T,n;
double a[N];
vector<double> sub,tmp;
bool check(double x,vector<double> v)
{
    for(int i=0;i<v.size()-1;i++)
    {
        if(v[i]==0) //特判一个区间覆盖两个点
        {
            continue;
        }
        else if(v[i]<x)//i点与i-1点之间的距离已经不足以容纳x
        {
            if(v[i+1]<x) return false;//判断i点与i+1点之间的距离是否足以容纳x,若否,false
            v[i+1]-=x;//若是,i点与i+1点之间的可容纳范围减少x
        }
        else
        {
            v[i]-=x;//可有可无,不影响答案//含义为把x塞到i点与i-1点之间
        }
    }
    return true;
}
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        cin>>a[i];
        sort(a+1,a+n+1);
        sub.clear();
        tmp.clear();
        for(int i=2;i<=n;i++)
        {
            tmp.push_back(a[i]-a[i-1]);//用于存储两点之间的距离
            sub.push_back(a[i]-a[i-1]);
            sub.push_back((a[i]-a[i-1])/2);//用于存储所有的区间长度可能
        }

        sort(sub.begin(),sub.end());
        for(int i=sub.size()-1;i>=0;i--)
        {
            if(check(sub[i],tmp))
            {
                printf("%.3lf\n",sub[i]);
                break;
            }
        }        
    }
}