求凸包 cogs896
cogs炸了,所以暂没有题面。
最基础的板子,因为根据点从左到右,横轴相同纵轴从下到上的顺序排了序,正向一遍求下壳(念什么?qiao:ke)再翻一遍求上壳,出入栈的原理就是根据叉乘逆时针为正,顺时针为负来判断是否外凸。想不明白可以画下图。
剩下就是扔个板子了。
#define e 1e-8 #include <cmath> #include <cstdio> #include <vector> #include <algorithm> using namespace std; int n; struct vec { double x,y; inline friend bool operator < (vec a,vec b) { if(a.x==b.x)return a.y<b.y; return a.x<b.x; } inline friend vec operator -(vec a,vec b) { return (vec){a.x-b.x,a.y-b.y}; } } a[10005]; int zhan[10005],head=0,vis[10005]; double ans=0; vector<vec> hh; double S(vec a,vec b) { return a.x*b.y-b.x*a.y; } bool check(vec a,vec b,vec c) { return S(b-a,c-a)>e; } double pf(double x) { return x*x; } double jl(vec a,vec b) { return sqrt(pf(a.x-b.x)+pf(a.y-b.y)); } int yjn() { // freopen("fc.in","r",stdin); // freopen("fc.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y); sort(a+1,a+n+1); zhan[++head]=1;zhan[++head]=2; for(int i=3;i<=n;i++) { while(head>1&&!check(a[zhan[head]],a[i],a[zhan[head-1]]))head--; zhan[++head]=i; } for(int i=1;i<=head;i++)vis[zhan[i]]=1,hh.push_back(a[zhan[i]]); head=0; zhan[++head]=n; zhan[++head]=n-1; for(int i=n-2;i>=1;i--) { while(head>1&&check(a[zhan[head]],a[zhan[head-1]],a[i]))head--; zhan[++head]=i; } for(int i=1;i<=head;i++)if(!vis[zhan[i]])hh.push_back(a[zhan[i]]),vis[zhan[i]]=1; for(int i=0,s=hh.size();i<s;i++) ans+=jl(hh[i],hh[(i+1)%s]); printf("%.2lf",ans); } int qty=yjn(); int main(){;}