(hdu 7.1.8)Quoit Design(最小点对——在n个点中,找到两个点间的最小距离)

题目:

Quoit Design

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 136 Accepted Submission(s): 77
 

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

2
0 0
1 1
2
1 1
1 1
3
-1.5 0
0 0
0 1.5
0


Sample Output

0.71
0.00
0.75


Author

CHEN, Yue


Source

ZJCPC2004


Recommend

JGShining

题目分析:

最小点对问题。所谓的最小点对问题就是,在n个点中找到2个点间的最短距离。这种题有两种思路:

1)直接暴力。看一看数据规模,n都在100000左右了,O(n^2)的算法,不出意外,会TLE。

2)分治。这道题用的是吉林大学的模板。直接套进去就行了。

与最小点对问题对应的是最大点对问题(不知道有没有这个名词,如果没有就当是我瞎编的吧。所谓的最大点对问题,在我的定义里就是,在n个点中找到两个点之间的最大距离)。能够产生最大距离的这两个点一定在凸包上,这时候我们只要枚举凸包上的任意两个点即可。其实这时候除了盲目枚举外,还有一种更好的算法来解决这个问题——旋转卡壳算法。

代码如下:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>

using namespace std;

/**
 * 求n个点中,2个点之间的最短距离。
 * 1)直接暴力。肯定会TLE
 * 2)使用吉林大学的模板
 */
const int N = 100005;
const double MAX = 10e100, eps = 0.00001;
struct Point {
	double x, y;
	int index;
};
Point a[N], b[N], c[N];
double closest(Point *, Point *, Point *, int, int);
double dis(Point, Point);
int cmp_x(const void *, const void*);
int cmp_y(const void *, const void*);
int merge(Point *, Point *, int, int, int);
inline double min(double, double);

int main(){
	int n;
	while(scanf("%d",&n)!=EOF,n){
		int i;
		for(i = 0 ; i < n ; ++i){
			scanf("%lf %lf",&a[i].x,&a[i].y);
		}
		qsort(a,n,sizeof(a[0]),cmp_x);
		for(i = 0 ; i < n ; ++i){
			a[i].index = i;
		}

		/**
		 * memcpy(目标地址,起始地址,n个字节)
		 * 作用:从起始地址拷贝n个字节到目标地址
		 * 头文件: 尽量把 <cstring>引入
		 *
		 */
		memcpy(b,a,n*sizeof(a[0]));

		qsort(b,n,sizeof(b[0]),cmp_y);

		double ans = closest(a,b,c,0,n-1);

		printf("%.2lf\n",ans/2);
	}

	return 0;
}

double closest(Point a[], Point b[], Point c[], int p, int q) {
	if (q - p == 1){
		return dis(a[p], a[q]);
	}
	if (q - p == 2) {
		double x1 = dis(a[p], a[q]);
		double x2 = dis(a[p + 1], a[q]);
		double x3 = dis(a[p], a[p + 1]);
		if (x1 < x2 && x1 < x3){
			return x1;
		}
		else if (x2 < x3){
			return x2;
		}
		else{
			return x3;
		}
	}
	int i, j, k, m = (p + q) / 2;
	double d1, d2;
	for (i = p, j = p, k = m + 1; i <= q; i++){
		if (b[i].index <= m){
			c[j++] = b[i];
		}
// 数组c 左半部保存划分后左部的点,  且对y 是有序的.
		else{
			c[k++] = b[i];
		}
	}
	d1 = closest(a, c, b, p, m);
	d2 = closest(a, c, b, m + 1, q);
	double dm = min(d1, d2);
// 数组c 左右部分分别是对y 坐标有序的,  将其合并到b.
	merge(b, c, p, m, q);
	for (i = p, k = p; i <= q; i++){
		if (fabs(b[i].x - b[m].x) < dm){
			c[k++] = b[i];
		}
	}
// 找出离划分基准左右不超过dm 的部分,  且仍然对y 坐标有序.
	for (i = p; i < k; i++){
		for (j = i + 1; j < k && c[j].y - c[i].y < dm; j++) {
			double temp = dis(c[i], c[j]);
			if (temp < dm){
				dm = temp;
			}
		}
	}
	return dm;
}
double dis(Point p, Point q) {
	double x1 = p.x - q.x, y1 = p.y - q.y;
	return sqrt(x1 * x1 + y1 * y1);
}
int merge(Point p[], Point q[], int s, int m, int t) {
	int i, j, k;
	for (i = s, j = m + 1, k = s; i <= m && j <= t;) {
		if (q[i].y > q[j].y){
			p[k++] = q[j], j++;
		}else{
			p[k++] = q[i], i++;
		}
	}
	while (i <= m){
		p[k++] = q[i++];
	}
	while (j <= t){
		p[k++] = q[j++];
	}

	memcpy(q + s, p + s, (t - s + 1) * sizeof(p[0]));
	return 0;
}
int cmp_x(const void *p, const void *q) {
	double temp = ((Point*) p)->x - ((Point*) q)->x;
	if (temp > 0){
		return 1;
	}
	else if (fabs(temp) < eps){
		return 0;
	}
	else{
		return -1;
	}
}
int cmp_y(const void *p, const void *q) {
	double temp = ((Point*) p)->y - ((Point*) q)->y;
	if (temp > 0){
		return 1;
	}
	else if (fabs(temp) < eps){
		return 0;
	}
	else{
		return -1;
	}
}
inline double min(double p, double q) {
	return (p > q) ? (q) : (p);
}
时间: 2024-12-28 11:07:37

(hdu 7.1.8)Quoit Design(最小点对——在n个点中,找到两个点间的最小距离)的相关文章

HDU 1007 Quoit Design (分治)

Quoit Design 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 ri

hdu 1007 Quoit Design 分治求最近点对

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

HDU 1007 Quoit Design(二分+浮点数精度控制)

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

HDU 1007 Quoit Design

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

分治 [HDU 1007] Quoit Design

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

HDU 1007 Quoit Design【计算几何/分治/最近点对】

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

Quoit Design(最近点对+分治)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007 Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 42865    Accepted Submission(s): 11128 Problem Description Have you ever played

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

hdu 3746 Cyclic Nacklace (KMP求最小循环节)

//len-next[len]为最小循环节的长度 # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int len; char a[100010]; int next[100010]; void Getnext() { int i=0,j=-1; next[0]=-1; while(i<=len) { if(j==-1||a[i]==a[j]) i