1. 程式人生 > >[BZOJ1007][HNOI2008]水平可見直線-[凸包]

[BZOJ1007][HNOI2008]水平可見直線-[凸包]

代碼 while algorithm bsp iostream blank top www truct

Description

傳送門

Solution

直接凸包,可見我們要求下凸包,又因為凸包的構成直線k是遞減的,直接排個序按套路走。

感覺數據好水。。一份AC代碼我自己手動出的數據都有bug。。然後我就加了一些小處理把我自己挑的bug給改了。(em這波操作)

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,top,ans[500010];
struct
node{int k,b,id; }y[500010],st[500010]; bool cmp(node a,node b){return (a.k==b.k)?a.b<b.b:a.k<b.k;} bool X(node a,node b,node c) {return 1.0*(a.b-b.b)*(c.k-a.k)>=1.0*(a.b-c.b)*(b.k-a.k);} int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d%d",&y[i].k,&y[i].b); y[i].id
=i; } sort(y+1,y+n+1,cmp); st[top=1]=y[1]; int now=1; for (;y[now+1].k==st[top].k;st[top]=y[now+1],now++); for (int i=now+1;i<=n;i++) { while (top>1&&X(st[top-1],st[top],y[i])) top--; st[++top]=y[i]; } for (int i=1;i<=top;i++) ans[i]=st[i].id; sort(ans
+1,ans+top+1); for (int i=1;i<=top;i++) printf("%d ",ans[i]); }

[BZOJ1007][HNOI2008]水平可見直線-[凸包]