SDOI2012最近最远点对

[题目描述]

给你n个点,求最近点对和最远点对,n<=100000

[题解]

计算几何裸题,由于本沙茶不会最近点对的二分算法,加上ws的出题人卡住了随机算法,于是苦B的打了一个2-d树交上去....

用2-d树做最近点对的应该就只有我这个若b了吧好心酸TAT,幸好没卡2-d树,不然白打了140行的代码啊...

代码量骤增(虽然我不知道二分的代码量怎么样,但这个140行的程序代码量算是很大的了)

这个代码最沙茶的地方在于:我用两个向量相乘来表示所选维度的值!!!!等我发现可以直接用下标搞的时候已经来不及改了TAT.另外我在划分的地方纠结了好久...

交了6次才A,我是有多弱啊......

Code:

program k_d_tree;{$INLINE ON}
type
        int=longint;
        real=extended;
        point=record x,y:real;end;
        line=record a,b,c:real;end;
const e=1e-9;maxn=200000;

operator -(a,b:point)c:Point;inline;
begin c.x:=a.x-b.x;c.y:=a.y-b.y;end;

operator *(a,b:point)c:real;inline;
begin c:=a.x*b.y-a.y*b.x;end;

operator /(a,b:point)c:real;inline;
begin c:=sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));end;

operator =(a:point;b:line)c:boolean;inline;
begin c:=b.a*a.x+b.b*a.y>b.c-e;end;

operator **(a:point;b:line)c:real;inline;
begin c:=b.a*a.x+b.b*a.y;end;

var
        i,j,k,m,n,pos:int;
        l:array[1..maxn*2]of line;
        a:array[0..maxn+1]of point;
        ll,rr,p:array[0..maxn*2]of int;
        x,t,y,s:point;li:line;
        ans,z:real;

procedure sort(ll,r,k:int);
var i,j:int;
begin
        i:=ll;j:=r;
        x:=a[(ll+r)>>1];
        repeat
                while a[i]**li<x**li do inc(i);
                while a[j]**li>x**li do dec(j);
                if i<=j then begin
                        t:=a[i];a[i]:=a[j];a[j]:=t;
                        inc(i);dec(j);
                end;
        until i>j;
        if(i<r)and(a[k]**li>=x**li)then sort(i,r,k);
        if(j>ll)and(a[k]**li<=x**li)then sort(ll,j,k);
end;

procedure build(rt,lb,rb:int);
var mid:int;
begin
        if random(2)=1 then l[rt].a:=1
                else l[rt].b:=1;
        mid:=(lb+rb)>>1;li:=l[rt];
        ll[rt]:=lb;rr[rt]:=rb;
        sort(lb,rb,mid);
        l[rt].c:=a[mid]**li;
        if mid>lb then build(rt<<1,lb,mid-1);
        if mid<rb then build(rt<<1+1,mid+1,rb);
end;

procedure ask(rt:int);
var mid:int;
begin
        mid:=(ll[rt]+rr[rt])>>1;
        if(mid<>pos)and(x/a[mid]<ans)then ans:=x/a[mid];
        if abs(x**l[rt]-l[rt].c)>ans+e then begin
                if(mid>ll[rt])and(x**l[rt]<a[mid]**l[rt])then ask(rt<<1)
                   else if mid<rr[rt] then ask(rt<<1+1);
        end else begin
                if mid>ll[rt] then ask(rt<<1);
                if mid<rr[rt] then ask(rt<<1+1);
        end;
end;

procedure sort1(l,r:int);
var i,j:int;
begin
        z:=a[(l+r)>>1].x;
        i:=l;j:=r;
        repeat
                while a[i].x<z do inc(i);
                while a[j].x>z do dec(j);
                if i<=j then begin
                        t:=a[i];a[i]:=a[j];a[j]:=t;
                        inc(i);dec(j);
                end;
        until i>J;
        if i<r then sort1(i,r);
        if j>l then sort1(l,j);
end;

procedure hull;
begin
        p[0]:=1;p[1]:=2;m:=1;
        for i:=3 to n do begin
                while(m>0)and((a[p[m-1]]-a[p[m]])*(a[p[m]]-a[i])>0)do dec(m);
                inc(m);p[m]:=i;
        end;
        for i:=n-1 downto 1 do begin
                while((a[p[m-1]]-a[p[m]])*(a[p[m]]-a[i])>0)do dec(m);
                inc(m);p[m]:=i;
        end;
end;

procedure up(var x:int);
begin x:=(x+1)mod(m+1);end;

procedure down(var x:int);
begin x:=x-1;if x=-1 then x:=m;end;

procedure main;
begin
        j:=1;ans:=0;
        for i:=1 to m do begin
                s:=a[p[i]]-a[p[i-1]];
                z:=s*(a[p[i]]-a[p[j]]);up(j);
                while(s*(a[p[i]]-a[p[j]])-z>-e)do begin
                        z:=s*(a[p[i]]-a[p[j]]);up(j);
                end;
                down(j);
                if(a[p[i]]/a[p[j]]>ans)then ans:=a[p[i]]/a[p[j]];
                if(a[p[i]]/a[p[i-1]]>ans)then ans:=a[p[i]]/a[p[i-1]];
        end;
        write(ans:0:2);
end;

begin
        assign(input,'data.txt');reset(input);
        assign(output,'k_d.out');rewrite(output);
        read(n);a[0].x:=1e30;a[0].y:=1e30;a[n+1]:=a[0];
        for i:=1 to n do read(a[i].x,a[i].y);
        fillchar(l,sizeof(l),0);
        build(1,1,n);
        ans:=1e30;
        for i:=1 to n do begin
                x:=a[i];pos:=i;ask(1);
        end;
        write(ans:0:2,' ');
        sort1(1,n);
        hull;
        main;
        close(input);close(output);
end.

-2012-12-27

好吧,我承认我nc了.

题目的数据并没有卡住随机算法,是我忘记加abs导致跳不了了...

各位神牛尽情地D我吧....

另外求能卡住最近点对的随机算法的数据

有的请私信Orz

有想法的也可以跟我聊一下

最远采样算法(PCL)是一种在三维空间中对云数据进行采样的算法。云是由大量离散组成的三维数据集,可用于表示物体的形状、结构和特征等信息。 最远采样算法的目标是从云数据中选择一组具有最大平均距离的离散集合。这样的采样结果能够更好地表示原始云数据的几何特征,可以用于云数据的降采样、特征提取等应用。 算法的实现步骤如下: 1. 随机选择一个初始作为起始采样; 2. 计算其他所有与已选取的采样之间的距离,并选择距离最远作为下一个采样; 3. 重复步骤2,直到选取足够数量的采样,或者达到预定的采样密度。 该算法的优是能够保留云数据的重要几何特征,尤其适用于包含明显结构的云数据。通过最远采样,可以有效地减少云数据的规模,提高后续处理的效率。 然而,最远采样算法也存在一些限制。例如,在云数据中存在噪音或稀疏区域时,算法可能无法准确地选择代表性的采样。此外,算法的性能受云数据的分布、密度和采样数量等因素的影响。 总之,最远采样算法是一种常用的云数据采样方法,通过选择具有最大平均距离的,能够保留云数据的几何特征。它在云处理和分析中具有广泛应用,可用于降采样、特征提取、配准等任务。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值