Tyvj1462 細節凸包

2022-04-10 01:01:11 字數 4010 閱讀 4526

p1462終於過了……說起來只是乙個簡單的凸包卻交了7次,足見此題資料之嚴。

我使用的是graham scan。先找到y座標最小,若y相同x最小點

【注1】的座標作為起始點p0,顯然其他點與p0的極角屬於[0,pi](此極角用arctan計算,特殊處理x=0與(x<0) and (y=0)時

【注2】。注意pascal的arctan返回值是(-pi/2,pi/2)……)。按極角從大到小,若極角相同則按至p0點距離由小到大

【注3】排序。

處理工作完成後,將p0與p1壓入棧,之後迴圈處理p2~pn-1若 棧頂 - i 在 棧頂-1 - 棧頂 向量的左側或平行(你應該知道什麼叫做叉積)則退棧,注意限定stacksize>=2

【注4】。最後將i壓入棧。

之後找題目要求的找到起始點開始輸出即可。注意精度

【注5】。

【注1】

網上的graham scan 教程均這麼認為,但經測試若按本演算法沒有x限制亦可。

【注2】

rte&wa了請參照此兩者。分別為pi/2和 pi。尤其是後者容易忘記考慮。

【注3】

由於之後兩向量共線即退棧,要保證一條線上的點最遠點能得以保留,則其應(在這些共線點中)最後處理。

資料input

50 0

1 21 0

0 20 1

output

0.0000 0.0000

0.0000 2.0000

1.0000 2.0000

1.0000 0.0000

【注4】全部共線時不限定棧大小會導致棧元素小於2,導致rte。

【注5】pascal請用extended。同時寫乙個cmp函式。a>b改寫成a-b>1e-12,依此類推。

附贈幾組資料(刪減版):

#1input

15372048554 194840794

1493722368 1609046412

764185136 846253213

1495038584 704170204

239709973 1230989664

908965419 1067337718

1296315630 717326987

576635090 1685913746

1232082109 1060706659

653622963 1534768490

448977811 741758128

244213649 77154157

911904634 230031831

1614797846 889031095

241142922 1949120387

output

239709973.0000 1230989664.0000

241142922.0000 1949120387.0000

1493722368.0000 1609046412.0000

1614797846.0000 889031095.0000

1495038584.0000 704170204.0000

911904634.0000 230031831.0000

244213649.0000 77154157.0000

#2input

41 1

2 23 3

4 4output

1.0000 1.0000

4.0000 4.0000

code:

program p1462;

const

eps=1e-15;

type

point=record

x,y:extended;

end;

vector=point;

var a,b:array[0..100002] of point;

ans:array[0..100002] of longint;

n,i,low,top:longint;

function len(a:vector):extended;inline;begin len:=sqrt(sqr(a.x)+sqr(a.y)); end;

function dot(a,b:vector):extended;inline;begin dot:=a.x*b.x+a.y*b.y; end;

function cos(a,b:vector):extended;inline;begin cos:=dot(a,b)/len(a)/len(b); end;

function cross(a,b:vector):extended;inline;begin cross:=a.x*b.y-a.y*b.x; end;

function cmp(a:extended):longint;inline;begin if a>eps then exit(1);if a<-eps then exit(-1);exit(0); end;

function minus(a,b:vector):vector;inline;begin minus.x:=a.x-b.x;minus.y:=a.y-b.y; end;

function cos(a:vector):extended;inline;begin cos:=a.x/len(a); end;

function angle(a:vector):extended;inline;var y:extended;begin if cmp(a.x)=0 then exit(pi/2);if (cmp(a.x)<0) and (cmp(a.y)=0) then exit(pi); y:=arctan(a.y/a.x);if cmp(y)<0 then exit(y+pi) else exit(y); end;

procedure qsort(l,r:longint);

var i,j:longint;

x,y:point;

begin

i:=l;j:=r;x:=b[(l+r) div 2];

repeat

while (cmp(angle(minus(b[i],b[1]))-angle(minus(x,b[1])))>0) or ((cmp(angle(minus(b[i],b[1]))-angle(minus(x,b[1])))=0) and (len(minus(b[i],b[1]))len(minus(x,b[1])))) do dec(j);

if i<=j then

begin

y:=b[i];

b[i]:=b[j];

b[j]:=y;

inc(i);

dec(j);

end;

until i>j;

if la[low].x)) then

low:=i;

top:=1;

for i:=1 to n do

if i<>low then

begin

inc(top);

b[top]:=a[i];

end;

b[1]:=a[low];

qsort(2,n);

top:=0;

push(1);push(2);

for i:=3 to n do

begin

while (cmp(cross(minus(b[ans[top]],b[ans[top-1]]),minus(b[i],b[ans[top]])))>=0) and (top>=2) do dec(top);

push(i);

end;

low:=1;

for i:=2 to top do

if (b[ans[i]].xfor i:=low to top do writeln(b[ans[i]].x:0:4,' ',b[ans[i]].y:0:4);

for i:=1 to low-1 do writeln(b[ans[i]].x:0:4,' ',b[ans[i]].y:0:4);

end.

tyvj 叢林探險

東非大裂谷中有一片神秘的叢林,是全世界探險家的樂園,著名黃 探險家bb一直想去試試。正好我國科學家2005年4月將首次對東非大裂谷進行科考,bb決定隨科考隊去神秘叢林探險。在出發之前,他蒐集了國內外有關神秘叢林探險的資料,並繪製成一張地圖 該地圖上有若干安全點 包括入口點和出口點 並將這些安全點編號...

HAProxy1 4 6後端Keepalive配置

keepalive 就是通常所稱的長連線,keepalive帶來的好處是可以減少tcp連線的開銷,這對於短response body的請求效果更加明顯。haproxy後端keepalive指的是在haproxy服務完一次與後端的互動 後,不關閉haproxy和後端 的連線,而是維護這個連線以備後續的...

146,流程控制語句

迴圈結構 for,for in,while,do while 選擇結構 if,switch 注 所有語句都必須在大括號裡面。取出範圍裡面所有的值 for v in 1.3 1 2 3注 v是常量!如果不需要用到迴圈中的常量v,可以使用下劃線 進行忽略 for in1.3 在while中,不需要在每乙...