Raid
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 10625   Accepted: 3192

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.  

Output

For each test case output the minimum distance with precision of three decimal placed in a separate line.

Sample Input

2
4
0 0
0 1
1 0
1 1
2 2
2 3
3 2
3 3
4
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0

Sample Output

1.414
0.000

Source

______________________________

平面最近点对,先按照x排序。然后二分。合并两个子问题时,先取两个子问题的最小值x,然后把切分的位置左右的点找出来(在x以内的)。 
然后把这些点按照y排序。然后枚举。显然是单调的,如果超过就跳出(强力剪枝)。注意计算距离时,如果两个点在同一个子集里,返回无限大的值。

________________分析懒得写了,直接搬运隔壁Orion_Rigel的______________

WA了好多次,最后试了一下把读入的坐标从int改成double就AC了

之后试了试另外一种,两个集合分开算的写法,不幸WA。嘛,不管了。

先放AC的代码:

 #include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const double INF=;
const int mxn=;
struct node{
double x,y;//坐标也可能是实数
int f;
}a[mxn];
int pt[mxn];
double ans;
int n;
int cmpx(node a,node b){
return a.x<b.x;
}
int cmpy(int b,int c){
return a[b].y<a[c].y;
}
double dist(node a,node b){
if(a.f==b.f)return INF;//如果是同集合的点,返回INF
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double mindis(int l,int r){//求最小距离
if(l==r)return INF;
if(r-l==) return dist(a[r],a[l]);
double res=INF;
int mid=(l+r)>>;
res=mindis(l,mid);
res=min(res,mindis(mid+,r));//分治
int cnt=;
int i,j;
for(i=l;i<=r;++i)//剪枝,只从可能更优的点里找
if(fabs(a[i].x-a[mid].x)<=res)pt[cnt++]=i;
sort(pt,pt+cnt,cmpy);
double mind=INF;
for(i=;i<cnt;i++){
for(j=i+;j<cnt;j++){
if(fabs(a[pt[i]].y-a[pt[j]].y)>=res)break;
if((mind=dist(a[pt[i]],a[pt[j]]))<res)res=mind;
}
}
return res;
}
int main(){
int T;
scanf("%d",&T);
int i,j;
while(T--){
scanf("%d",&n);
int x,y;
for(i=;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y),a[i].f=;
int nn=n*;
for(i=n+;i<=nn;i++)scanf("%lf%lf",&a[i].x,&a[i].y),a[i].f=;
sort(a+,a+nn+,cmpx);
ans=mindis(,nn);
printf("%.3lf\n",ans);
}
return ;
}

下面是WA的算法,路过的大神求指点……

 #include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int mxn=;
struct node{
double x,y;
}s[mxn],a[mxn];
int cmpx(node a,node b){
return a.x<b.x;
}
int cmpy(node a,node b){
return a.y<b.y;
}
double mans;
int n;
int mxx=;
inline double dist(int x1,int y1,int x2,int y2){
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void cl(int l,int r){
if(l>=r-)return;
int mid=(l+r)/;
cl(l,mid);
cl(mid,r);
if(r-l>mans)return;
int i,j;
int dx=mid-mans;
int dx2=mid+mans;
for(i=;i<=n;i++){
if(s[i].x<dx)continue;
if(s[i].x>mid)break;
for(j=;a[j].x<dx2 && j<=n;j++){
if(a[j].x<dx)continue;
if(a[j].y<s[i].y-mans || a[j].y>s[i].y+mans)continue;
mans=min(mans,dist(s[i].x,s[i].y,a[j].x,a[j].y));
}
}
return;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
int i,j;
for(i=;i<=n;i++){
scanf("%lf%lf",&s[i].x,&s[i].y);
}
for(i=;i<=n;i++){
scanf("%lf%lf",&a[i].x,&a[i].y);
}
sort(s+,s+n+,cmpx);
sort(a+,a+n+,cmpx);
mans=;
cl(,*n);
printf("%.3lf\n",mans);
}
}

POJ3714 Raid的更多相关文章

  1. poj3714 Raid(分治求平面最近点对)

    题目链接:https://vjudge.net/problem/POJ-3714 题意:给定两个点集,求最短距离. 思路:在平面最近点对基础上加了个条件,我么不访用f做标记,集合1的f为1,集合2的f ...

  2. POJ-3714 Raid 平面最近点对

    题目链接:http://poj.org/problem?id=3714 分治算法修改该为两个点集的情况就可以了,加一个标记... //STATUS:C++_AC_2094MS_4880KB #incl ...

  3. POJ3714 Raid 分治/K-D Tree

    VJ传送门 简要题意:给出两个大小均为\(N\)的点集\(A,B\),试在\(A\)中选择一个点,在\(B\)中选择一个点,使得它们在所有可能的选择方案中欧几里得距离最小,求出这个距离 下面给出的两种 ...

  4. 【poj3714】 Raid

    http://poj.org/problem?id=3714 (题目链接) 现在才搞平面最近点对..感觉有点尴尬 题意 给出平面上两组点,每组n个,求两组点之间最短距离 Solution1 平面最近点 ...

  5. 【POJ3714】Raid:平面最近点对

    Description After successive failures in the battles against the Union, the Empire retreated to its ...

  6. $Poj3714/AcWing\ Raid$ 分治/平面最近点对

    $AcWing$ $Sol$ 平面最近点对板子题,注意要求的是两种不同的点之间的距离. $Code$ #include<bits/stdc++.h> #define il inline # ...

  7. 『Raid 平面最近点对』

    平面最近点对 平面最近点对算是一个经典的问题了,虽然谈不上是什么专门的算法,但是拿出问题模型好好分析一个是有必要的. 给定\(n\)个二元组\((x,y)\),代表同一平面内的\(n\)个点的坐标,求 ...

  8. 一张“神图”看懂单机/集群/热备/磁盘阵列(RAID)

    单机部署(stand-alone):只有一个饮水机提供服务,服务只部署一份 集群部署(cluster):有多个饮水机同时提供服务,服务冗余部署,每个冗余的服务都对外提供服务,一个服务挂掉时依然可用 热 ...

  9. 什么是RAID?RAID有什么用?RAID原理

    什么是RAID 硬盘是个很脆弱的东西,它经常会坏掉.所以,为了保证服务器可靠耐用,硬盘必须时时刻刻保持可用.所以有了RAID这个东西.它的目的是将好几个硬盘合并在一起,就算硬盘坏了一个,剩下还有好几个 ...

随机推荐

  1. HTTP请求与响应方式

    HTTP请求格式 当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息,HTTP请求信息由3部分组成: l   请求方法URI协议/版本 l   请求头(Request Hea ...

  2. Studio 从入门到精通 (一)

    目标:Android Studio新手–>下载安装配置–>零基础入门–>基本使用–>调试技能–>构建项目基础–>使用AS应对常规应用开发 AS简介 经过2年时间的研 ...

  3. [原创]gerrit上分支操作记录(创建分支、删除分支)

    Git分支对于一个项目的代码管理而言,是十分重要的! 许多久用git的朋友可能已经掌握的很牢固了,但对于一些初涉git的童鞋来说,可能还不是很熟悉. 在此,我将自己的一些操作经历做一梳理,希望能帮助到 ...

  4. 纯CSS3实现兔斯基简单害羞表情

    前言 很不巧前天突然就感冒了,都怪自己吃太多饼干导致上火了.整个人都无精打采.本来想多做几个兔斯基表情的,但身体发热很难受.所以就只完成一个简单点的表情耍一耍. 正文 先看一下这个简单到不能再简单的小 ...

  5. 我们为什么要使用NodeJS

    科普文一则,说说我对NodeJS(一种服务端JavaScript实现)的一些认识,以及我为什么会向后端工程师推荐NodeJS. "Node.js 是服务器端的 JavaScript 运行环境 ...

  6. [6]Telerik TreeView 复选框

    参考连接:http://demos.telerik.com/aspnet-mvc/razor/treeview/clientsideapi 问题: Telerik TreeView 选择或取消 父选项 ...

  7. Linux 字符集转化

    命令行"iconv --list" 查看Linux操作系统支持的字符集 iconv_open 设置字符集转化 --iconv_t iconv_open(const char *to ...

  8. Oracle11G安装之后

    本人对oracle还处于摸索阶段,今天安装了一下Oracle11G, 安装之后,后台管理端的登录地址:https://172.16.10.75:1158/em 1.使用之前设置的dba管理员密码账号登 ...

  9. IBatis.Net学习笔记七--日志处理

    IBatis.Net中提供了方便的日志处理,可以输出sql语句等调试信息. 常用的有两种:1.输出到控制台:   <configSections>    <sectionGroup  ...

  10. Android:支持多选的本地相册

    前段时间在做一个动态发布功能,需要用到图片上传.一开始直接调用的系统相册和相机,由于系统相机不支持多选,就花点时间做了个本地相册,在此开源下. 先上截图,依次为选择相册界面.相册详情界面.查看图片大图 ...