HDU1007 Quoit Design

来源:互联网 发布:apache 运行 ruby 编辑:程序博客网 时间:2024/06/05 18:29

Quoit Design

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)


Problem Description
Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded.
In the field of Cyberground, the position of each toy is fixed, and the ring is carefully designed so it can only encircle one toy at a time. On the other hand, to make the game look more attractive, the ring is designed to have the largest radius. Given a configuration of the field, you are supposed to find the radius of such a ring.

Assume that all the toys are points on a plane. A point is encircled by the ring if the distance between the point and the center of the ring is strictly less than the radius of the ring. If two toys are placed at the same point, the radius of the ring is considered to be 0.
 

Input
The input consists of several test cases. For each case, the first line contains an integer N (2 <= N <= 100,000), the total number of toys in the field. Then N lines follow, each contains a pair of (x, y) which are the coordinates of a toy. The input is terminated by N = 0.
 

Output
For each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places.
 

Sample Input
20 01 121 11 13-1.5 00 00 1.50
 

Sample Output
0.710.000.75


本题大意:
本题的题目背景是对圈圈套礼品游戏,游戏已经设置好保证一次最多只能套到一个礼品,但又让那个圈的直径最大。转化一下思路,其实也就是求平面内最短的两个点的
距离。
用到分治思想。
divide:将所有点按x坐排序后,用中间坐标mid把点分为左右两堆,递归求出左边最小值left,和右边的最小值right

conquer:现在已经得到了left,和right。由于刚刚是两边分开计算的,所以真正的最小值可能在中间,设minnum = min(left,right), 这时候就要在[mid -min,mid+min]这个区间里去搜索。这部分就只能暴力搜索了。不过注意剪枝,可以按y坐标排序进行剪枝。

具体请看代码:

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <cmath>#include <algorithm>using namespace std;#define maxn 100005#define inf 0x7fffffffint n ;struct Node {    double x;    double y;};Node arr[maxn];double ans = inf;int cmp(Node a ,Node b){//    if(a.x == b.x){//        return a.y <  b.y;//    }    return a.x < b.x;}int cmp1(Node a ,Node b){//    if(a.y == b.y){//        return a.x <  b.x;//    }    return a.y < b.y;}double divide(int low, int high);double Merge(int low , int mid,int high,double minnum);double dis(int low,int high);double dis(Node low,Node high);int main(){    while(scanf("%d",&n),n){        ans = inf * 1.0;        for(int i = 0; i < n; i++){            scanf("%lf%lf",&arr[i].x,&arr[i].y);        }       sort(arr,arr+n,cmp);//        for(int i = 0 ; i < n;i++){//            cout << arr[i].x << " " << arr[i].y << endl;//        }        ans = divide(0,n);        printf("%.2lf\n",ans / 2.0);    }    return 0;}double divide(int low, int high){    if(low + 1 >= high){        return inf;    }    if(low + 2 == high){        double tmp =  dis(low,high-1);/* 00       if(tmp < ans){            ans = tmp;        }*/         return tmp;    }    if(low < high){        int mid = (low + high) / 2;       double left = divide(low,mid);       double right =divide(mid,high);       double minnum = min(left,right);       double tmp = Merge(low,mid,high,minnum);/*       if(tmp < ans){            ans = tmp;       }*/       return tmp;    }}double Merge(int low , int mid,int high, double minnum){    vector<Node> node;    node.clear();       Node tmp ;    for(int i = mid; i < high;i++){        if(arr[i].x > arr[mid].x + minnum){            break;        }        tmp.x = arr[i].x;        tmp.y = arr[i].y;        node.push_back(tmp);    }    for(int i = mid - 1; i >=low;i--){        if(arr[i].x < arr[mid].x - minnum){            break;        }        tmp.x = arr[i].x;        tmp.y = arr[i].y;        node.push_back(tmp);    }    int len = node.size();    double ans = minnum;    sort(node.begin(),node.end(),cmp1);    for(int i = 0; i < len;i++){        for(int j = i - 1; j >= 0  ; j--){            if(node[i].y - node[j].y > ans){                break;            }            double path = dis(node[i],node[j]);            if(path < ans){                ans = path;            }        }    }    return ans;}double dis(int low,int high){    double path = 0.0;    path = (arr[low].x - arr[high].x)*(arr[low].x - arr[high].x) +            (arr[low].y - arr[high].y) * (arr[low].y - arr[high].y);    return sqrt(path);}double dis(Node low,Node high){    double path = 0.0;    path = (low.x - high.x)*(low.x - high.x) +            (low.y - high.y) * (low.y - high.y);    return sqrt(path);}

 





0 0
原创粉丝点击