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