1. 程式人生 > >[日常摸魚]bzoj1007[HNOI2008]水平可見直線-半平面交(對偶轉凸包)

[日常摸魚]bzoj1007[HNOI2008]水平可見直線-半平面交(對偶轉凸包)

blog hnoi2008 str check -- 水平 urn har tor

不會寫半平面交…然後發現可以轉成對偶凸包問題

具體見這裏:http://trinkle.blog.uoj.ac/blog/235

相關的原理我好像還是不太懂…orz

#include<cstdio>
#include<algorithm>
const int N=50005;
inline int read()
{
    int s=0,f=1;char c=getchar();
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){s=s*10
+c-0;c=getchar();} return s*f; } struct P{int x,y,i;}p[N]; int n,r,s[N]; bool cmp(P a,P b){return a.x<b.x||(a.x==b.x&&a.y<b.y);} P operator-(P a,P b){return (P){a.x-b.x,a.y-b.y};} long long cross(P a,P b){return 1ll*a.x*b.y-1ll*a.y*b.x;} long long check(P a,P b,P c){return cross(b-a,c-a);}
int main() { n=read();int i; for(i=1;i<=n;i++){p[i].x=read(),p[i].y=-read(),p[i].i=i;}std::sort(p+1,p+n+1,cmp); for(i=1;i<=n;i++) { while(r>1&&check(p[s[r-1]],p[s[r]],p[i])<=0)--r;s[++r]=i; } for(i=1;i<=r;i++)s[i]=p[s[i]].i;std::sort(s+1,s+r+1);
for(i=1;i<=r;i++)printf("%d ",s[i]); return 0; }

[日常摸魚]bzoj1007[HNOI2008]水平可見直線-半平面交(對偶轉凸包)