POJ 3714 Raid
Description
After successive failures in the battles against the Union, the Empire retreated to its last stronghold. Depending on its powerful defense system, the Empire repelled the six waves of Union's attack. After several sleepless nights of thinking, Arthur, General of the Union, noticed that the only weakness of the defense system was its energy supply. The system was charged by N nuclear power stations and breaking down any of them would disable the system.
The general soon started a raid to the stations by N special agents who were paradroped into the stronghold. Unfortunately they failed to land at the expected positions due to the attack by the Empire Air Force. As an experienced general, Arthur soon realized that he needed to rearrange the plan. The first thing he wants to know now is that which agent is the nearest to any power station. Could you, the chief officer, help the general to calculate the minimum distance between an agent and a station?
Input
The first line is a integer T representing the number of test cases.
Each test case begins with an integer N (1 ≤ N ≤ 100000).
The next N lines describe the positions of the stations. Each line consists of two integers X (0 ≤ X ≤ 1000000000) and Y (0 ≤ Y ≤ 1000000000) indicating the positions of the station.
The next following N lines describe the positions of the agents. Each line consists of two integers X (0 ≤ X ≤ 1000000000) and Y (0 ≤ Y ≤ 1000000000) indicating the positions of the agent.
看不懂题面没有关系,我来大致讲一下:给定平面上n个黑点和n个白点(就这样认为吧),求最近的黑点与白点之间的距离。多组输入。输出保留三位小数。
其实这题就是裸的平面最近点对,只需把相同颜色的点之间的距离设为INF即可。
我在这里不做详解,只是稍稍讲一下怎么做。
首先,最近点对 对于一个区间(x坐标)显然 有三种情况:全都在中线左边,全都在中线右边,或者一个在左一个在右。而前两种显然可以递归处理。
那么,我们只需先把点按x坐标排序,然后处理过中线的点对即可。我们定义solve(l,r)来计算在l个点到第r个点之间的最近点对,那么solve(l,r)=min{solve(l,mid),solve(mid+1,r),过中线的最小值}
于是,我们发现在求过中线的最近点对之前我们已经知道了当前的最优解now。由于距离<=now的点离中线的距离一定<=now,那么我们可以把左右两边符合条件的点分别先抠出来。
现在问题变成了:对于任意一个点,是否有点在以它为半径,now为圆心的圆内?
但圆内的点并不好求,我们就可以把圆拓展成矩形:
我们可以发现些什么?是不是最多只有6个点在这些矩形内?
把点再按y轴排一遍序,对于每个点弄个上下边界,一路扫过去即可。总的复杂度为O(nlogn)。
还有一件事:这道题居然卡精度!卡精度!卡精度!请注意你的精度!
当然还有一件非常鬼畜的事(c++选手):POJ上用printf("%.3lf")时就一直WA,改成printf("%.3f")才可以AC。不知所措。
下面贴代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 200010
#define INF (1LL<<60)
using namespace std;
typedef long long llg;
struct data{
int x,y; bool w;
bool operator < (const data &h)const{return x<h.x;}
}s[maxn],ss[maxn];
llg ans,now;
int n,a[maxn],b[maxn],la,lb,T;
inline llg ji(int x){return (llg)x*(llg)x;}
inline llg dis(int x,int y){ return s[x].w==s[y].w?INF:ji(s[x].x-s[y].x)+ji(s[x].y-s[y].y);}
void work(){
for(int i=1,l=1,r=1;i<=la;i++){
while(s[b[r]].y-s[a[i]].y<now && r<=lb) r++;
while(s[a[i]].y-s[b[l]].y>now && l<=lb) l++;
for(int j=l;j<r;j++) ans=min(ans,dis(a[i],b[j]));
}
}
void solve(int l,int r){
if(l==r) return;
int mid=l+r>>1;
llg m=s[mid].x; now=(llg)sqrt(ans);
solve(l,mid); solve(mid+1,r);
la=0,lb=0;
for(int i=l;i<=mid;i++)
if(m-s[i].x<now) a[++la]=i;
for(int i=mid+1;i<=r;i++)
if(s[i].x-m<now) b[++lb]=i;
work();
int k1=l,k2=mid+1,kk=l-1;
while(k1<=mid && k2<=r)
if(s[k1].y<=s[k2].y) ss[++kk]=s[k1++];
else ss[++kk]=s[k2++];
while(k1<=mid) ss[++kk]=s[k1++];
while(k2<=r) ss[++kk]=s[k2++];
for(int i=l;i<=r;i++) s[i]=ss[i];
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n); ans=INF;
for(int i=1;i<=n*2;i++){
scanf("%d %d",&s[i].x,&s[i].y);
s[i].w= i<=n;
}
sort(s+1,s+n*2+1); solve(1,n<<1);
printf("%.3f\n",sqrt(ans));
}
}
POJ 3714 Raid的更多相关文章
- 最近点对问题 POJ 3714 Raid && HDOJ 1007 Quoit Design
题意:有n个点,问其中某一对点的距离最小是多少 分析:分治法解决问题:先按照x坐标排序,求解(left, mid)和(mid+1, right)范围的最小值,然后类似区间合并,分离mid左右的点也求最 ...
- poj 3714 Raid【(暴力+剪枝) || (分治法+剪枝)】
题目: http://poj.org/problem?id=3714 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27048#prob ...
- poj 3714 Raid(平面最近点对)
Raid Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7473 Accepted: 2221 Description ...
- POJ 3714 Raid(计算几何の最近点对)
Description After successive failures in the battles against the Union, the Empire retreated to its ...
- POJ 3714 Raid 近期对点题解
版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/.未经本作者同意不得转载. https://blog.csdn.net/kenden23/article ...
- POJ 3714 Raid(平面近期点对)
解题思路: 分治法求平面近期点对.点分成两部分,加个标记就好了. #include <iostream> #include <cstring> #include <cst ...
- (洛谷 P1429 平面最近点对(加强版) || 洛谷 P1257 || Quoit Design HDU - 1007 ) && Raid POJ - 3714
这个讲的好: https://phoenixzhao.github.io/%E6%B1%82%E6%9C%80%E8%BF%91%E5%AF%B9%E7%9A%84%E4%B8%89%E7%A7%8D ...
- 【POJ 3714】 Raid
[题目链接] http://poj.org/problem?id=3714 [算法] 分治求平面最近点对 [代码] #include <algorithm> #include <bi ...
- 【POJ 3714】Raid
[题目链接]:http://poj.org/problem?id=3714 [题意] 给你两类的点; 各n个; 然后让你求出2*n个点中的最近点对的距离; 这里的距离定义为不同类型的点之间的距离; [ ...
随机推荐
- 【代码笔记】iOS-关于UIFont的一些define
一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...
- iOS--归档和解档(Archiver)、(UnArchiver)
一.已有类型的归档和解档 首先来看一个简单的例子: //第一方式:归档对象 //对象-->文件 NSArray *array = [NSArray arrayWithObjects:@" ...
- Android 自定义控件(一)
本文用一个简单的例子来说明一下自定义控件的步骤实现,自定义控件有几种实现类型,分别为继承自view完全自定义,继承现有的 控件实现特定效果,继承viewgroup实现布局类等: 本文研究的是继承自vi ...
- 如何开启win7端口的图文教程
Windows 7/Vista/XP/2003等系统中的远程终端服务是一项功能非常强大的服务,下面来教教大家如何开启端口:打开“控制面板”中的“Windows防火墙”,点击左侧的“高级设置” 右击“入 ...
- js 判断多个一样的name
var items = document.getElementsByName("spec_spec_1[]"); alert(items.length); for (i = 0; ...
- thinkphp5命名规范
类的命名采用驼峰法,并且首字母大写.如:User.UserType[不需要加后缀.如IndexController是没必要的,应当直接为Index.接口或者抽象类也保持这个规范] 属性命名采用驼峰法, ...
- eclipse插件汇总
subclipse http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA 话说eclipse组织也出了一个svn的插件,但 ...
- js 获取当前系统时间
Js获取当前日期时间及其它操作 var myDate = new Date();myDate.getYear(); //获取当前年份(2位)myDate.getFullYear(); //获取完整的年 ...
- AEAI Portlet开发心得
1 背景概述 Portlet是AEAI Portal组件API,是基于Java的Web组件,由Portlet容器管理,并由容器处理请求,生产动态内容.AEAI Portal中已经预置了许多Portle ...
- GY编辑平台产品总结
产品亮点一.实时直播流的关键帧识别并展示选择频道的实时流并播放后,会在窗口中自动展示关键帧图片:配对选择关键帧的截图即确定了素材的入点,出点:编辑平台图如下所示:二.广告自动识别与监测方案1. 制作样 ...