1. 程式人生 > >hdu6325 /// 上凸包

hdu6325 /// 上凸包

memset bit one 技術 題解 sed code printf 負數

題目大意:

給定n 為n個點

給定n個點的坐標

兩個點(xi,yi) (xj,yj)之間的花費是 xi*yj-yi*xj (可能為負數)

要求從點1經過若幹個點到點n最小花費的路徑 且路徑要按x軸方向(即x遞增)

輸出路徑順序經過的點的編號

使花費最小 而花費又可能為負數 那麽就盡量使得花費為負數

所以點的方向一直為順時針的話就能使得花費最小 也就是一個上凸包

題解:https://www.cnblogs.com/mountaink/p/9591414.html

BTW 這題似乎沒有考慮精度誤差 加上精度誤差的判斷反而會WA

技術分享圖片
#include <bits/stdc++.h>
#define
INF 0x3f3f3f3f #define LL long long #define mem(i,j) memset(i,j,sizeof(i)) using namespace std; const int N=2e5+5; const int MOD=1e9+7; const double EPS=1e-8; struct P { double x,y; int id=0; P(){} P(double x,double y):x(x),y(y){} P operator -(P p) { return P(x-p.x,y-p.y); } P operator
+(P p) { return P(x+p.x,y+p.y); } double dot(P p) { return x*p.x+y*p.y; } double det(P p) { return x*p.y-y*p.x; } bool operator <(const P& p)const { if(x!=p.x) return x<p.x; if(y!=p.y) return y<p.y; return id<p.id; } bool operator ==(const
P& p)const { return x==p.x && y==p.y; } void scf() { scanf("%lf%lf",&x,&y); } }p[N], ans[N]; int n; int andrew() { sort(p+1,p+1+n); int c=0; for(int i=1;i<=n;i++) { if(i>1 && p[i]==ans[c-1]) continue; while(c>1 && (p[i]-ans[c-1]).det(ans[c-2]-ans[c-1])>=0) { if((p[i]-ans[c-1]).det(ans[c-2]-ans[c-1])>0) c--; else if(ans[c-1].id>p[i].id) c--; else break; } ans[c++]=p[i]; } return c; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) p[i].scf(), p[i].id=i; int c=andrew(); for(int i=0;i<c-1;i++) printf("%d ",ans[i].id); printf("%d\n",ans[c-1].id); } return 0; }
View Code

hdu6325 /// 上凸包