方师傅来到了一个二维平面。他站在原点上,觉得这里风景不错,就建了一个房子。这个房子是n个点的凸多边形,原点一定严格在凸多边形内部。有m个人也到了这个二维平面。现在你得到了m个人的坐标,你要判断这m个人中有多少人在房子内部。点在凸多边形边上或者内部都认为在房子里面。
标签:put clu += ros 一个人 接下来 std names 题解
题解:我们先随便选择一个点,然后对凸多边形进行三角剖分。这样每一个三角形管辖的范围都能看成是极角上的一段区间。在查询时我们二分找到对应点在那个三角形管辖的范围内,然后判断那个点是否在这个三角形里即可。
#include <cstdio> #include <cstring> #include <iostream> using namespace std; typedef long long ll; int n,m; int ans,lastans; struct point { int x,y; point() {} point(int a,int b) {x=a,y=b;} point operator - (const point &a) const {return point(x-a.x,y-a.y);} ll operator * (const point &a) const {return (ll)x*a.y-(ll)y*a.x;} }p[100010],q; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int rd() { int ret=0,f=1; char gc=nc(); while(!isdigit(gc)) {if(gc==‘-‘) f=-f; gc=nc();} while(isdigit(gc)) ret=ret*10+(gc^‘0‘),gc=nc(); return ret*f; } int main() { n=rd(); int i,l,r,mid; for(i=1;i<=n;i++) p[i].x=rd(),p[i].y=rd(); m=rd(),lastans=1; for(i=1;i<=m;i++) { q.x+=rd()*lastans,q.y+=rd()*lastans; if((p[2]-p[1])*(q-p[2])<0) lastans=-1; else if((p[n]-p[1])*(q-p[n])>0) lastans=-1; else { l=2,r=n+1; while(l<r) { mid=(l+r)>>1; if((p[mid]-p[1])*(q-p[mid])>0) l=mid+1; else r=mid; } if((p[l]-p[l-1])*(q-p[l])>=0) lastans=1,ans++; else lastans=-1; } } printf("%d",ans); return 0; }//4 -2 -2 2 -2 2 2 -2 2 3 5 5 4 4 0 3
标签:put clu += ros 一个人 接下来 std names 题解
原文地址:http://www.cnblogs.com/CQzhangyu/p/7898259.html