为什么要写这个题、、经典啊,当然,别以为我用分治做的,不过主要思想还是那神奇的六个点共存(一个h*2h的矩形中最多能放下多少个点使得两两距离不超过h)

其实我是在这里看到的

http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lineSweep

排个序,然后扫描过去,每次确定Y的范围,暴力找每个点(其实这是O(1)的)

蛮不错的哦。

写完后发现比分治写的快了好多啊,估计是我不会写分治吧T_T,总之,现在跑到了rank 4了。。。

数据结构就是这样的直接啊!

/* **********************************************
Author : wuyiqi
Created Time: 2013-8-24 12:54:35
File Name : ruocai.cpp
*********************************************** */
#include <cstdio>
#include <cmath>
#include <stack>
#include <algorithm>
using std::stack;
using std::pair;
using std::make_pair;
#define L x->c[0]
#define R x->c[1]
#define KT root->c[1]->c[0]
const int maxn = 200010;
struct node{
node *c[2] , *fa;
int id,sz;
double val,x;
inline bool d() {
return fa->c[0] == this;
}
inline void setc(int d,node *s) {
c[d] = s;
s->fa = this;
}
inline void up() {
sz = c[0]->sz + c[1]->sz + 1;
}
}NODE[maxn],*null=&NODE[0];
node *ID[maxn];
int top;
struct Splay_tree{
node *root;
void Rotate(node *x,int f){
node *y = x->fa;
y->setc(!f,x->c[f]);
x->fa = y->fa;
if(y->fa != null) y->fa->setc(!y->d(),x);
x->setc(f,y);
y->up();
}
void Splay(node *x,node *goal) {
while(x->fa!=goal) {
if(x->fa->fa == goal) Rotate(x,x->d());
else {
int f = x->fa->d();
x->d() == f ? Rotate(x->fa,f) : Rotate(x,!f);
Rotate(x,f);
}
}
x->up();
if(goal == null) {
root = x;
}
}
void RTO(int k,node *goal) {
node *x = root;
while(L->sz + 1 != k) {
if(k < L->sz + 1) x = L;
else {
k -= L->sz + 1;
x = R;
}
}
Splay(x,goal);
}
void insert(node* &x,node *y) {
if(x == null) {
x = y;
return ;
}
if(y->val <= x->val) {
insert(x->c[0],y);
x->c[0]->fa = x;
} else {
insert(x->c[1],y);
x->c[1]->fa = x;
}
x->up();
}
node* new_node(int id,double x,double y) {
node* tmp = &NODE[++top];
tmp->fa = null;
tmp->val = y;
tmp->x = x;
tmp->sz = 1;
tmp->id = top;
tmp->c[0] = tmp->c[1] = null;
ID[id] = tmp;
return tmp;
}
void insert(int id,double x,double y) {
node *tmp = new_node(id,x,y);
insert(root,tmp);
}
void init() {
root = null;
}
void Del_root() {
node *t = root;
if(t->c[1] != null) {
root = t->c[1];
RTO(1,null);
root->c[0] = t->c[0];
if(root->c[0] != null)
root->c[0]->fa = root;
} else {
root = root->c[0];
}
root->fa = null;
if(root != null) root->up();
} void Del(node *tmp) {
Splay(tmp,null);
Del_root();
}
node* find_pre(node *x,double v) {
if(x == null) return null;
if(x->val < v) {
node *tmp = find_pre(x->c[1],v);
return tmp == null ? x : tmp;
}
else {
return find_pre(x->c[0],v);
}
}
node* find_succ(node *x,double v) {
if(x == null) return null;
if(x->val > v ) {
node *tmp = find_succ(x->c[0],v);
return tmp == null ? x : tmp;
} else {
return find_succ(x->c[1],v);
}
}
void search(double a,double b,double &ans,node* x){
if(x == null) return ;
double c = x->x , d = x->val;
double cost = sqrt((a-c)*(a-c) + (b-d)*(b-d));
if(cost < ans) ans = cost;
if(x->c[0] != null) search(a,b,ans,x->c[0]);
if(x->c[1] != null) search(a,b,ans,x->c[1]);
}
void gao(double x,double y,double &ans) {
node *pre = find_pre(root,y-ans) ;
node *succ = find_succ(root,y+ans);
if(pre == null || succ == null) while(1);
Splay(pre,null);
Splay(succ,root);
search(x,y,ans,KT);
}
void vist(node *x) {
if(x!=null) {
printf("%d x = %lf y = %lf lson=%d rson=%d\n",x->id,x->x,x->val,x->c[0]->id,x->c[1]->id);
if(x->c[0]!=null) vist(x->c[0]);
if(x->c[1]!=null) vist(x->c[1]);
}
}
void debug(){
puts("*******");
vist(root);
puts("*****");
}
}spt;
void prepare() {
null->id = 0;
null->c[0] = null->c[1] = null->fa = NULL;
null->sz = null->val = 0;
top = 0;
}
double x[maxn] , y[maxn];
bool by_x(int a,int b) {
return x[a] > x[b];
}
int id[maxn];
double sqr(double a) { return a * a; }
int main()
{
int n;
while(scanf("%d",&n),n) {
prepare();
spt.init();
for(int i = 0; i < n; i++) {
id[i] = i;
scanf("%lf%lf",&x[i],&y[i]);
}
if(n == 1){
puts("0.00");
continue;
}
std::sort(id,id+n,by_x);
spt.insert(0,-1e100,-1e100);
spt.insert(0,-1e100,1e100);
double ans = 1e50 ;
int pt = 0;
for(int i = 0; i < n; i++) {
if(ans == 0) break;
while(pt < i && x[id[pt]] > x[id[i]] + ans ) {
if(spt.root->sz == 2) break;
spt.Del(ID[id[pt]]);
pt++;
}
if(spt.root->sz == 2) {
spt.insert(id[i],x[id[i]],y[id[i]]);
} else {
spt.gao(x[id[i]],y[id[i]],ans);
spt.insert(id[i],x[id[i]],y[id[i]]);
}
}
printf("%.2f\n",ans*0.5);
}
return 0;
}

hdu 1007 最近点对问题(Splay解法)的更多相关文章

  1. hdu 1007最近点对问题

    先说下题意,很简单,给n个点的坐标,求距离最近的一对点之间距离的一半.第一行是一个数n表示有n个点,接下来n行是n个点的x坐标和y坐标,实数. 这个题目其实就是求最近点对的距离.主要思想就是分治.先把 ...

  2. zoj 2107&&hdu 1007最近点对问题

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1107 Quoit Design Time Limit: 5 Seconds   ...

  3. HDU 1007 Quoit Design(二分+浮点数精度控制)

    Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  4. HDU 1007 Quoit Design(经典最近点对问题)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1007 Quoit Design Time Limit: 10000/5000 MS (Java/Oth ...

  5. HDU 1007 Quoit Design 平面内最近点对

    http://acm.hdu.edu.cn/showproblem.php?pid=1007 上半年在人人上看到过这个题,当时就知道用分治但是没有仔细想... 今年多校又出了这个...于是学习了一下平 ...

  6. HDU 1007:Quoit Design(分治求最近点对)

    http://acm.hdu.edu.cn/showproblem.php?pid=1007 题意:平面上有n个点,问最近的两个点之间的距离的一半是多少. 思路:用分治做.把整体分为左右两个部分,那么 ...

  7. HDU 1007(套圈 最近点对距离)

    题意是求出所给各点中最近点对的距离的一半(背景忽略). 用分治的思想,先根据各点的横坐标进行排序,以中间的点为界,分别求出左边点集的最小距离和右边点集的最小距离,然后开始合并,分别求左右点集中各点与中 ...

  8. hdu 1007 Quoit Design(分治法求最近点对)

    大致题意:给N个点,求最近点对的距离 d :输出:r = d/2. // Time 2093 ms; Memory 1812 K #include<iostream> #include&l ...

  9. HDU 1007 Quoit Design(计算几何の最近点对)

    Problem Description Have you ever played quoit in a playground? Quoit is a game in which flat rings ...

随机推荐

  1. 业余写的一个播放器SDK,求点意见

    好久没写博客了 现大致花了半年时间私下写一个音频SDK,想请csdn的达人提点意见,看看还需要增加哪些功能 我对这个的定位如下: 可以在游戏开发中播放音乐,作为一般的音频播放器后端,作为音频编辑器后端 ...

  2. KVM虚拟机介绍

    一 KVM虚拟机简介 kernel-based Virtual Machine的简称,是一个开源的 系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中.它使用Linux ...

  3. qingshow “不积跬步无以至千里,不积小流无以成江海”。--荀子《劝学篇》 用tomcat+花生壳搭建自己的web服务器+域名(参考)

    链接地址:http://www.blogjava.net/qingshow/archive/2010/01/17/309846.html 用tomcat搭建web服务器 目标:免费拥有自己的网站及域名 ...

  4. 使用C语言实现字符串中子字符串的替换

    描述:编写一个字符串替换函数,如函数名为 StrReplace(char* strSrc, char* strFind, char* strReplace),strSrc为原字符串,strFind是待 ...

  5. HDU 1251 统计难题 (字符串-Trie树)

    统计难题 Problem Description Ignatius近期遇到一个难题,老师交给他非常多单词(仅仅有小写字母组成,不会有反复的单词出现),如今老师要他统计出以某个字符串为前缀的单词数量(单 ...

  6. hdoj 1286 找新朋友 【数论之欧拉函数】

    找新朋友 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  7. 使用awk和grep做简单的统计

    grep 或 egrep 或awk 过滤两个或多个关键词: grep -E ‘123|abc’ filename // 找出文件(filename)中包含123或者包含abc的行 egrep ‘123 ...

  8. 做自己的Android ROM,屏蔽对framework中的系统APK的签名检查

    最近两天一直在尝试更新Android中的关键库以达到定制ROM的效果,中间比较曲折,记录下来供自己和大家参考. 因为我需要基于Android的原生代码做一定的修改,所以如果无法将我自己编译出的APK或 ...

  9. 创建webservice 用service.xml配置(复杂点的方法)

    用Axis2实现Web Service,虽然可以将POJO类放在axis2/WEB-INF/pojo目录中直接发布成Web Service,这样做不需要进行任何配置,但这些POJO类不能在任何包中.这 ...

  10. FreeLink开源呼叫中心设计思想

    上一篇大概说了国内外优秀的呼叫中心系统: 国内外优秀呼叫中心系统简单介绍 借鉴上述呼叫中心系统,我们的设计新一代呼叫中心例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY ...