hdu1007

/*
*最近点对的问题
*/

#include 
#include 
#include 
using namespace std;
const int SIZE = 100005;
const int L = -1;
const int R = 1;

typedef struct
{
int index;
double x;
double y; /用于记录坐标点/
}coord;

coord num[SIZE], c[SIZE]/用作辅助数组/;

double getDistance(coord &bi1, coord &bi2) /求得两点之间的距离/
{
return sqrt(pow(bi1.x - bi2.x, 2.0) + pow(bi1.y - bi2.y, 2.0));
}

bool cmpx(coord &bi1, coord &bi2)
{
if (bi1.x == bi1.x)
return bi1.y < bi2.y;
else
return bi1.x < bi2.x;
}

bool cmpy(coord &bi1, coord &bi2)
{
if (bi1.y == bi2.y)
return bi1.x < bi2.x;
else
return bi1.y < bi2.y;
}

inline double min(double &bi1, double &bi2, double &bi3)
{
double minLength;
minLength = bi1 > bi2 ? bi2 : bi1;
minLength = minLength > bi3 ? bi3 : minLength;
return minLength;
}

inline double minDist(double &bi1, double &bi2)
{
if (bi1 > bi2)
return bi2;
return bi1;
}

double divide_conquer(int low, int high) /分治法求最小距离/
{
double dis;
int count = high - low;
if (count == 0)
{
return 0;
}
else if (count == 1) /两个数/
{
dis = getDistance(num[low], num[high]);
}
else if (count == 2) /三个数/
{
double temp1, temp2, temp3;
temp1 = getDistance(num[low], num[low + 1]);
temp2 = getDistance(num[low + 1], num[high]);
temp3 = getDistance(num[low], num[high]);
dis = min(temp1, temp2, temp3);
}
else /大于三个数的情况/
{
double leftmin, rightmin, min;
int mid = (low + high) / 2;
int p = 0;
int i, j;

    leftmin = divide_conquer(low, mid);  /*求得左边部分的最小值*/
    rightmin = divide_conquer(mid + 1, high);  /*求得右边部分的最小值*/
    dis = minDist(leftmin, rightmin);  

    /*下面从所有坐标点中找出所有x在leftCoord到rightCoord之间的点*/
    for (i = low; i <= mid; i++)
    {
        double leftCoord = num[mid].x - dis;
        if (num[i].x >= leftCoord)
        {
            c[p].index = L;  /*标识属于左边部分*/
            c[p].x = num[i].x;
            c[p].y = num[i].y;
            p++;
        }
    }
    for ( ; i <= high; i++)
    {
        double rightCoord = num[mid].x + dis;
        if (num[i].x <= rightCoord)
        {
            c[p].index = R;  /*标识属于右边部分*/
            c[p].x = num[i].x;
            c[p].y = num[i].y;
            p++;
        }
    }
    sort(c, c + p, cmpy);   /*找到的点再从小到大按照y排序一次*/
    for (i = 0; i < p; i++)
    {

/*错误出现在这里,上面我是只搜索了左边,并且只计算了7个y值比c[i].y大的点到c[i]的距离,
可是实际上y值比c[i].y小的点也有可能与c[i]取得最小值,所以说上面的程序有错误。真正正确
的解答如下,那就是要搜索所有的点,并计算7个y值比c[i].y大的点到c[i]的距离,由于距离是两个
点之间产生的,一个点的y值比另一个点小,那么必然有另一个点的y值比一个点的大,由于这种关系,
从而保证了搜索出来的是最小的距离!
*/
for (j = 1; (j <= 7) && (i + j < p); j++)
{
if (c[i].index != c[i + j].index) /最小值只可能出现在两个分别属于不同的边的点上/
{
min = getDistance(c[i], c[i + j]);
if(min < dis)
dis = min;
}
}
}
}
return dis;
}

int main ()
{
int n;
while (cin >> n && n != 0)
{
double result = 0;

    for (int i = 0; i < n; i++)
    {
        num[i].index = 0;
        cin >> num[i].x >> num[i].y;
    }  

    sort (num, num + n, cmpx);  

    result = divide_conquer(0, n - 1);  

    printf("%.2lf\n", result / 2);
}
//system ("pause");
return 0;

}

时间: 2024-10-31 15:55:27

hdu1007的相关文章

HDU1007 Quoit Design 【分治】

Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 30505    Accepted Submission(s): 8017 Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat

Quoit Design(hdu1007)最近点对问题。模版哦!

Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 30919 Accepted Submission(s): 8120 Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings

hdu1007 平面最近点对(暴力+双线程优化)

突发奇想,用双线程似乎可以优化一些暴力 比如说平面最近点对这个题目,把点复制成2份 一份按照x排序,一份按照y排序 然后双线程暴力处理,一份处理x,一份处理y 如果数据利用x递减来卡,那么由于双线程,它卡不住y 如果数据利用y递减来卡,那么卡不住x 这样暴力n^2就可以过了 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algori

HDU1007(求最近两个点之间的距离)

一年前学长讲这题的时候,没听懂,自己搜解题报告也看不懂,放了一年.如今对分治和递归把握的比一年前更加熟悉,这题也就解决了. 题意:给你一堆点让你求最近两点之间距离的一半,如果用暴力的话O(n*n)明显会超时,那么我们就用分治思想,将所有点按照横坐标x排序,然后取中间的mid,分着求1-mid,mid-n,这样递归求解,递归只需要logn级别就可以完成递归,这有点类似二分思想. 1.我们取左边点对最小和右边点对最小比较,取最小的,记做d 2:但是最近点有可能一个点在左边,一个点在右边,所以要单独考

[HDU1007]Quoit Design

题目描述 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

Quoit Design(hdu1007)

---恢复内容开始--- Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 47126    Accepted Submission(s): 12323 Problem Description Have you ever played quoit in a playground? Quoit is a game

HDU1007:Quoit Design——题解

http://acm.hdu.edu.cn/showproblem.php?pid=1007 题目大意:给n个点,求点对最短距离/2. —————————————————————— 平面分治裸题. 暂时还不想讲为什么这么做. 所以原理暂割. #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespac

模拟/hdu 1008 Elevator

题意 开始电梯在0层 给出n个指令,每个代表下一步停到哪层 每往上一层需要6秒,往下一层需要4秒,停止需要5秒 求总时间 分析 数据很小,模拟即可喵- Accepted Code 1 /* 2 PROBLEM:hdu1007 3 AUTHER:Nicole Lam 4 MEMO:模拟 5 */ 6 7 8 #include<cstdio> 9 using namespace std; 10 11 int main() 12 { 13 int n; 14 scanf("%d"

2015-11-3-Training(for 2014th)

A:(hdu1081) 题意: 求和最大的子矩阵 解决: 先考虑一维数组,可以O(n)复杂度求出 和值最大的连续子序列. 同理,对每一行维护前缀和,然后枚举从 l 列到 r 列,每行的 l 列到 r 列可以通过前缀和O(1)求出,然后对每行的 l 列和r 列之间的和值作为一维数组的元素,O(n)求出答案. 总复杂度 :O(n3) 1 #include <bits/stdc++.h> 2 3 const int MAXN = 133; 4 5 int n; 6 int ma[MAXN][MAXN