【HDU 5721】Palace(平面最近点对)

【HDU 5721】Palace(平面最近点对)

Palace

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)

Total Submission(s): 404    Accepted Submission(s): 104

Problem Description

The last trial Venus imposes on Psyche is a quest to the underworld. She is to take a box and obtain in it a dose of the beauty of Prosperina, queen of the underworld.

There are n palaces
in the underworld, which can be located on a 2-Dimension plane with (x,y) coordinates
(where x,y are
integers). Psyche would like to find the distance of the closest pair of two palaces. It is the password to enter the main palace.

However, the underworld is mysterious and changes all the time. At different times, exactly one of the n palaces
disappears.

Psyche wonders what the distance of the closest pair of two palaces is after some palace has disappeared.

Print the sum of the distance after every single palace has disappeared.

To avoid floating point error, define the distance d between
palace (x1,y1) and (x2,y2) as d=(x1?x2)2+(y1?y2)2.

Input

The first line of the input contains an integer T (1≤T≤5),
which denotes the number of testcases.

For each testcase, the first line contains an integers n (3≤n≤105),
which denotes the number of temples in this testcase.

The following n lines
contains n pairs
of integers, the i-th
pair (x,y) (?105≤x,y≤105) denotes
the position of the i-th
palace.

Output

For each testcase, print an integer which denotes the sum of the distance after every single palace has disappeared.

Sample Input

1
3
0 0
1 1
2 2

Sample Output

12

Hint

If palace $ (0,0) $ disappears,$ d = (1-2) ^ 2 + (1 - 2) ^ 2 = 2 $;

If palace $ (1,1) $ disappears,$ d = (0-2) ^ 2 + (0 - 2) ^ 2 = 8 $;

If palace $ (2,2) $ disappears,$ d = (0-1) ^ 2 + (0-1) ^ 2 = 2 $;

Thus the answer is $ 2 + 8 + 2 = 12 $。

Source

BestCoder 2nd Anniversary

Recommend

wange2014   |   We have carefully selected several similar problems for you:  5722 5719 5718 5717 5716

题目大意:给出平面上n个点的坐标,可以得到平面最近点对的距离。

现求分别删掉第1~n个点时,平面上最近点对的距离的和。(这里防止精度问题,只要求距离的平方

可知对于不删点时可以求得最近点对。

如果删掉的点不是最近点对的两个端点,最近距离还是这两个点的距离。(会有n-2)次

其次,如果删除其中任何一个点,标记一下,然后再分别跑一边最近点,统计即可。

最近点对用分治法,模板类。

此外注意开long long

代码如下:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread(ch) freopen(ch,"r",stdin)
#define fwrite(ch) freopen(ch,"w",stdout)

using namespace std;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int msz = 100100;
const int mod = 1e9+7;
const double eps = 1e-8;

struct Point
{
	LL x,y;
	int id;
};

LL dist(Point a,Point b)
{
	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}

Point p[msz];
Point tmpt[msz];

bool cmpxy(Point a,Point b)
{
	if(a.x != b.x) return a.x < b.x;
	return a.y < b.y;
}

bool cmpy(Point a,Point b)
{
	return a.y < b.y;
}

LL d;
int pt[2];

void Closest_Pair(int left,int right,int opt)
{
	if(left == right) return;
	LL tmp;
	if(left + 1 == right)
	{
		if(p[left].id != opt && p[right].id != opt)
		{
			tmp = dist(p[left],p[right]);
			if(d > tmp)
			{
				d = tmp;
				if(opt == -1)
				{
					pt[0] = p[left].id;
					pt[1] = p[right].id;
				}
			}
		}
		return;
	}

	int mid = (left+right)/2;
	Closest_Pair(left,mid,opt);
	Closest_Pair(mid+1,right,opt);

	int k = 0;

	for(int i = left; i <= right; ++i)
	{
		if(p[i].id != opt && abs(p[mid].x - p[i].x) <= d)
			tmpt[k++] = p[i];
	}

	sort(tmpt,tmpt+k,cmpy);

	for(int i = 0; i < k; ++i)
	{
		for(int j = i+1; j < k && tmpt[j].y - tmpt[i].y < d; ++j)
		{
			tmp = dist(tmpt[i],tmpt[j]);
			if(d > tmp)
			{
				if(opt == -1)
				{
					pt[0] = tmpt[i].id;
					pt[1] = tmpt[j].id;
				}
				d = tmp;
			}
		}
	}
}

int main()
{
	//fread("");
	//fwrite("");

	int t,n;

	scanf("%d",&t);

	while(t--)
	{
		scanf("%d",&n);
		for(int i = 0; i < n; ++i)
		{
			scanf("%lld%lld",&p[i].x,&p[i].y);
			p[i].id = i;
		}

		sort(p,p+n,cmpxy);

		d = INF;
		Closest_Pair(0,n-1,-1);
		LL ans = 1LL*d*(n-2);

		d = INF;
		Closest_Pair(0,n-1,pt[0]);
		ans += d;

		d = INF;
		Closest_Pair(0,n-1,pt[1]);
		ans += d;
		printf("%lld\n",ans);
	}

	return 0;
}
时间: 2024-10-13 14:00:10

【HDU 5721】Palace(平面最近点对)的相关文章

HDU 5721 Palace BestCoder 2nd Anniversary (平面最近点对)

Palace Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 465    Accepted Submission(s): 118 Problem Description The last trial Venus imposes on Psyche is a quest to the underworld. She is to ta

【HDU5721 BestCoder 2nd AnniversaryD】【平面最近点对 分治写法+KD-tree写法】Palace 平面最近点对

Palace Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 260    Accepted Submission(s): 72 Problem Description The last trial Venus imposes on Psyche is a quest to the underworld. She is to tak

BestCoder 2nd Anniversary 1004&amp;Hdu 5721 Palace

题意:给定n个点,对于每次消失一个点,问剩下的点中的最短距离是多少,然后所有最短距离的和. 分析:1.模版题,然而没模版的我码了半天. 2.(1)只要不删掉与最短距离相关的两个点,那么最短距离不变. (2)若与最短距离的点相关,删掉点后,重新算一遍. /************************************************ Author :DarkTong Created Time :2016/7/18 14:01:14 File Name :d.cpp *******

平面最近点对

HDU 1007 求平面最近点对距离的一半 #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> using namespace std; const double eps = 1e-7; const int MAXN = 100010; const double INF = 1e20; struct Point

hdu 1007 Quoit Design, 平面最近点对

平面最近点对的经典做法就是分治.所有点先按x再按y排序,然后取中间位置的点,利用其x坐标值将点划分成左右两部分,分别求出两侧的最近点对(设其距离为δ),然后合并.参看下面的图片(来自guyulongcs的专栏,http://blog.csdn.net/guyulongcs/article/details/6841550)合并的时候需要注意,大致有两种做法,一种是把分界线两侧δ范围内的点分别加进一个数组,然后对右侧数组按y坐标值排序,之后依次为每个左侧数组中的点,在右侧数组中寻找与其y坐标值最近的

kd树解平面最近点对

早上起来头有点疼,突然就想到能不能用kd树解平面最近点对问题,就找了道题试了一下,结果可以,虽然效率不高,但还是AC了~ 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007 题目要求平面上最近点对间距离的一半. 思路如下:先建立一棵树,所有点插入树中,之后为每个点查询其最近点,枚举找到最小值.注意查询的时候不要让点自己跟自己比.个人感觉,这种写法也可以达到O(nlogn)的复杂度.建树分区间的时候,按x,y中跨度大的一个来分,应该就接近O(nl

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

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

平面最近点对(分治nlogn)

平面最近点对,是指给出平面上的n个点,寻找点对间的最小距离 首先可以对按照x为第一关键字排序,然后每次按照x进行分治,左边求出一个最短距离d1,右边也求出一个最短距离d2,那么取d=min(d1, d2) 然后只需考虑横跨左右两侧的点,不妨枚举左侧的点pi 那么很显然的是如果pi距离中间的点超过了d,便可以直接舍去,只需考虑距离中间点小于d的点 这样一来就可以对每个pi画一个边长为2d的正方形,易证,矩形内最多存在8个点. 那么关键问题就是要快速找这8个点 朴素做法是对分治后的点进行快排,这样复

POJ 3714 Raid(平面最近点对)

解题思路: 分治法求平面最近点对,点分成两部分,加个标记就好了. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <iomanip>