極角排序 POJ1696

2021-07-11 21:27:12 字數 2162 閱讀 2852

vj題目連線

一種奇怪的蟲子不能右轉且走過路線之間不能有交點,吃植物才能存活,給出植物的座標,求蟲子要怎樣走才能活得最久(吃的植物越多活越久)

輸入:樣例數,n組樣例,每組給出乙個n,然後n行每行給出3個數,分別是植物編號、植物x座標、植物y座標

輸出:能吃的最大植物數目,並給出路線

因為蟲子只能左轉且路線不能有交點,很容易想到讓蟲子逆時針螺旋地去吃植物,由外到內,可以將所有植物吃完。因為逆時針路線一定是左轉,螺旋線保證不相交,從最外到最內是肯定可以吃完所有植物的。

怎樣構造這樣的螺旋線呢?這要用極角排序。從最下方的點開始,將這個點作為基點,對其他所有點進行極角排序,然後取極角最小點,重新設立為基點,對剩餘點重新排序,依次類推直至剩最後乙個點。

為什麼要從最下點開始?因為這樣可以保證其他點都在上方,這樣就可以使其他點與該點的極角都》=0,這樣可以以x軸正方向為基線找出夾角最小的點。之後由找到的新點為基點,可以保證其他未選擇的點都在上乙個點與新基點連線的一側,這樣就可以以這條連線作為基線求最小極角。

怎樣求對極角進行排序?簡單的做法是用sort函式,然後自定義乙個cmp比較函式,大致如下:

//極角排序規則 

bool cmp(const point &p1, const point &p2)

//兩線重合時選擇距離更小的

else

if(fabs(tmp)<=eps && dis(pointset[cnt],p1)return

true;

} return

false;

}

這裡沒有直接求角度,而是利用外積來判斷,外積函式如下:

//小於0,說明向量p0p1的極角大於p0p2的極角

double multiply(point p1,point p2,point p0)

顯然,若p1p0與p2p0的外積》0,則p1在p2右側(若以上述的基線為水平線),相反,若外積<0,則p1在p2左側,而我們要的極角最小的點即在最右側的點。若外積為0,則三點共線,我們需要優先選擇更靠近基點的點。

#include 

#include

#include

#include

#include

#define eps 0.00000001

using

namespace

std;

struct point

;const

int maxn=55;

point pointset[maxn]; //輸入的點集

point ans[maxn]; //輸出的點集

int n; //點的個數

int cnt; //當前判斷基點

//小於0,說明向量p0p1的極角大於p0p2的極角

double multiply(point p1,point p2,point p0)

//p1p2距離

double dis(point p1,point p2)

//極角排序規則

bool cmp(const point &p1, const point &p2)

//兩線重合時選擇距離更小的

else

if(fabs(tmp)<=eps && dis(pointset[cnt],p1)return

true;

} return

false;

} int main()

}//初始基點

cnt=0;

//排序

sort(pointset+1,pointset+n,cmp);

ans[cnt]=pointset[cnt++];

for(i=2;i//依次設立基點排序

sort(pointset+cnt,pointset+n,cmp);

ans[cnt]=pointset[cnt++];

}ans[cnt]=pointset[cnt++];

printf("%d",cnt);

for(i=0;iprintf(" %d",ans[i].num);

}printf("\n");

}return

0;}

POJ 1696 極角排序

題目中指定了ant爬行時的幾種規則,從中我們可以知道ant是按照當前所處位置,對其他的plant進行極角排序後,選擇角度最小過去,重複,一直到走到最後乙個plant。sort一發就可以了 include include include include include const double eps...

poj1696(極角排序,貪心)

恢復內容開始 題意 有n個點,規定起點,每次只能向左走,不能與之前的路徑交叉,求最多能經過幾個點。思路 其實這題因為起點的y座標最小,那麼經過的點數一定就是所有的點數n,然後顯然我們優先選擇偏移角度最小的點作為後繼,也就是極角最小,那麼每次選擇乙個點後都按極角公升序排一次即可。我的 是遍歷了一遍,因...

POj 1696 Space Ant (極角排序)

題意 乙隻螞蟻,只會向左轉,現在給出平面上很多個點,求解一種走法,能使得螞蟻能經過的點最多,每個頂點該螞蟻只能經過一次,且所行走的路線不能發生交叉.對於題目所輸入的點,先找出最左下方的頂點 即縱座標最小的頂點 然後對剩下的頂點按照對與左下點的極角排序,然後反覆找最左下的點,反覆進行極角排序,同時記錄...