hdu 4932

Miaomiao's Geometry

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2569    Accepted Submission(s): 649


Problem Description
There are N point on X-axis . Miaomiao would like to cover them ALL by using segments with same length.

There are 2 limits:

1.A point is convered if there is a segments T , the point is the left end or the right end of T.
2.The length of the intersection of any two segments equals zero.

For example , point 2 is convered by [2 , 4] and not convered by [1 , 3]. [1 , 2] and [2 , 3] are legal segments , [1 , 2] and [3 , 4] are legal segments , but [1 , 3] and [2 , 4] are not (the length of intersection doesn't equals zero), [1 , 3] and [3 , 4] are not(not the same length).

Miaomiao wants to maximum the length of segements , please tell her the maximum length of segments.

For your information , the point can't coincidently at the same position.
 

 

Input
There are several test cases.
There is a number T ( T <= 50 ) on the first line which shows the number of test cases.
For each test cases , there is a number N ( 3 <= N <= 50 ) on the first line.
On the second line , there are N integers Ai (-1e9 <= Ai <= 1e9) shows the position of each point.
 

 

Output
For each test cases , output a real number shows the answser. Please output three digit after the decimal point.
 

 

Sample Input
3 3 1 2 3 3 1 2 4 4 1 9 100 10
 

 

Sample Output
1.000 2.000 8.000
 
 
析:x轴上有n个点,要求用线段覆盖,被覆盖的点只能在线段的端点处,而且每条线段长度必须相同,求满足要求的最长线段长度。可知线段长度只能是在相邻两个点之间的距离中选择,要注意的是线段长度还可能是相邻两点距离的一半,即(xi-xi-1)/2,比如 1,12,28,35,50,66这组数据,12和28恰好可以分为左线段的左端点以及右线段右端点,中间在20处交汇,故计算出所有可能线段长度,进行枚举,注意为了节省时间可筛掉重复的部分
 
 
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <functional>
#define ll long long
#define ull unsigned ll
#define Inf 0x7fffffff
#define maxn 1000005
#define maxm 100005
#define P pair<int, int>
using namespace std;
const int N = 3005;
int t, n, m, len, ans;
double f[55], dis[115];
bool check(double d){
    double nxt = -Inf;  //保存以当前位置为起始点的线段结束位置
    for(int i = 2; i <= n; i ++){
        double tmp = f[i]-f[i-1];
        if(nxt > f[i])
            return false;
        if(tmp == d)    //恰好为线段长度,可用一条线段覆盖
            continue;
        if(tmp < d){    //当前点与前一点不可用同一条线段覆盖,单独成一条线段
            nxt = f[i]+d;
        }else if(f[i]-d < nxt){ //前一点与当前点>d但<2*d,单独成一条线段
            nxt = f[i]+d;
        }
    }
    return true;
}
int main(){
    scanf("%d", &t);
    while(t--){
        ans = 0;
        scanf("%d%lf", &n, &f[1]);
        for(int i = 2; i <= n; i ++){
            scanf("%lf", &f[i]);
        }
        sort(f+1, f+n+1);
        for(int i = 2; i <= n; i ++){
            dis[++ans] = f[i]-f[i-1];
            dis[++ans] = dis[ans-1]/2;
        }
        double res = 0;
        sort(dis+1, dis+ans+1);
        ans = unique(dis+1, dis+ans+1)-dis-1; //筛重
        for(int i = ans; i; i --){
            if(check(dis[i])){
                res = dis[i];
                break;
            }
        }
        printf("%.3lf\n", res);
    }
    return 0;
}
View Code

 

posted @ 2020-04-22 16:48  傲-寒  阅读(147)  评论(1编辑  收藏  举报