【計算幾何+二分】 POJ 2318
阿新 • • 發佈:2018-11-10
【題目大意】給定一個箱子的左上角座標和右上角座標。給定n個隔板的端點座標【保證隔板不相交】,內部隔間從0到n編號。
給定m個玩具的座標【保證玩具在箱子內部且不在隔板上】,每個玩具在一個隔間內。
問每個隔間內有多少個玩具。
首先用叉積判玩具在隔板的哪個方位。我們利用二分找到玩具右邊的第一個隔板,然後把這個隔間的答案加一。
具體有些細節看程式碼吧。
#include<cstdio> #include<cstring> using namespace std; struct point{ int x,y; point(int _x=0,int _y=0){x=_x,y=_y;} friend inline int operator *(const point &a,const point &b){ return a.x*b.y-a.y*b.x; } friend inline point operator +(const point &a,const point &b){ return point(a.x+b.x,a.y+b.y); } friend inline point operator -(const point &a,const point &b){ return point(a.x-b.x,a.y-b.y); } }toy,up[10000],down[10000],U,D; int ans[233333],n,m; //a is toy //(b->a)*(b->c) //如果玩具在隔板bc的左邊,返回真,否則返回假。 bool check(point a,point b,point c){ return (c-b)*(a-b)>0; } int main(){ while(scanf("%d",&n)&&n){ memset(ans,0,sizeof(ans)); scanf("%d",&m); scanf("%d%d%d%d",&U.x,&U.y,&D.x,&D.y); for(int i=1;i<=n;++i){ scanf("%d%d",&up[i].x,&down[i].x); up[i].y=U.y,down[i].y=D.y; } for(int i=1;i<=m;++i){ scanf("%d%d",&toy.x,&toy.y); //注意二分的上下界。 int l=1,r=n+1; while(l<r){ int mid=(l+r)>>1; if(check(toy,down[mid],up[mid])) r=mid; else l=mid+1; } //注意隔間的編號。第L個隔板左邊對應第L-1個隔間。 ans[l-1]++; } for(int i=0;i<=n;++i) printf("%d: %d\n",i,ans[i]); putchar('\n'); } }