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个点中的最近点对的距离; 这里的距离定义为不同类型的点之间的距离; [ ...
随机推荐
- Xcode cannot launch because the device is locked.
When you plug in your iPhone, it will ask you to trust the computer. If you already trust and unlock ...
- 【代码笔记】iOS-对UIView进行截图
一,效果图. 二,工程图. 三,代码. RootViewController.m #import "RootViewController.h" @interface RootVie ...
- Oracle与MySQL的区别
1. Oracle是大型数据库而Mysql是中小型数据库,Oracle市场占有率达40%,Mysql只有20%左右,同时Mysql是开源的而Oracle价格非常高. 2. Oracle支持大并发,大访 ...
- NGINX高性能Web服务器详解(读书笔记)
原文地址:NGINX高性能Web服务器详解(读书笔记) 作者:夏寥寥 第4章 Nginx服务器的高级配置 4.1 针对IPv4的内核7个参数的配置优化 说明:我们可以将这些内核参数的值追加到Linu ...
- 常用的主机监控Shell脚本
最近时不时有朋友问我关于服务器监控方面的问题,问常用的服务器监控除了用开源软件,比如:cacti,nagios监控外是否可以自己写shell脚本呢?根据自己的需求写出的shell脚本更能满足需求,更能 ...
- XAML中的特殊符号几空白字符处理
阅读目录 介绍 详细 处理 Demo下载 介绍 XAML标记语言是基于xml的,所以很多xml中的特殊符号在XAML也是需要处理的. 详细 (取自msdn) 字符 Entity 注释 &(“a ...
- 浴室随想——RogueLike随想
好玩的RogueLike 0 不同的追求 1 从追求中寻找商机 2 更的直接方法 3 我的追求 4 我的方法 5 好玩的RogueLike RogueLike游戏很好玩,因为你永远不知道接下来会发生什 ...
- Android中使用dimen定义尺寸(转)
(转自:http://blog.csdn.net/yuzhiboyi/article/details/7696174) 最近,遇到了一种定义尺寸的方法,类似于C里面的宏定义一样,其实以前已经见过了这种 ...
- Docker+OpenvSwitch搭建VxLAN实验环境
一.概述 1.环境:我这里是2台linux机器(host1和host2),发行版是kali2.0, ...
- [转]MongoDB基本命令用
本文转自:http://www.cnblogs.com/liyonghui/p/mongodb.html 成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作. 输 ...