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个点中的最近点对的距离; 这里的距离定义为不同类型的点之间的距离; [ ...
随机推荐
- NSPredicate
NSPredicate 1. 正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则的字符串.通常被用来检索.替换那些符合某个模式的文本. 2. iOS中正则使用 有三种(NSPredicate, ...
- Android对应用程序签名
1.首先签名是个什么东西. 应用程序签名就是为你的程序打上一种标记,来作为你自己的标识. 2.为什么要进行数字签名 这是Android系统的要求,每一个应用程序必要要经过数字签名才可能安装到系统中,能 ...
- 悟语 KISS 简单至上 keep it simple stupid
引自 PostgreSQL Server Programming-Second Edition page81: 大部分时候,我们不需要快速的代码,而是能用的程序. remember that most ...
- 关于激活Bentley软件详细步骤介绍(再补充一个)
在安装完ContextCapture软件之后,大家怀着迫不及待的心情双击了运行快捷键.但是很遗憾的是,会产生下面的提示窗口: 也许大家并不在意,就觉得关掉这个窗口不就行了.然而,头疼的问题来了.这个窗 ...
- (视频) 《快速创建网站》 3.2 WordPress多站点及Azure在线代码编辑器 - 扔掉你的ftp工具吧,修改代码全部云端搞定
本文是<快速创建网站>系列的第6篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 访问本系列目录,请点击:http://devopshub.cn/tag ...
- 腾讯Tinker初入门总结
- CentOS vsftp安装与配置
详细配置说明:. http://www.cnblogs.com/app-lin/p/5189762.html 1.安装vsftpd yum install vsftpd 2.启动/重启/关闭vsftp ...
- 7 个顶级的 HTML5 Canvas 动画赏析
HTML5确实是一项改革浏览器乃至整个软件行业的新技术,它可以帮助我们Web开发者很方便地在网页上实现动画特效,而无需臃肿的Flash作为支撑.本文分享7个顶级的HTML5 Canvas 动画,都有非 ...
- Java Security:公钥私钥、数字签名、消息摘要是什么
1. 鲍勃有两把钥匙,一把是公钥,另一把是私钥. 2. 鲍勃把公钥送给他的朋友们----帕蒂.道格.苏珊----每人一把. 3. 苏珊要给鲍勃写一封保密的信.她写完后用鲍勃的公钥加密,就可以达到保密的 ...
- 【mysql】数据库使用的一些规范
一.MySQL存在的问题 优化器对复杂SQL支持不好 对SQL标准支持不好 大规模集群方案不成熟,主要指中间件 ID生成器,全局自增ID 异步逻辑复制,数据安全性问题 Online DDL HA方案不 ...