pku 2318 TOYS(叉积,二分)

题意:一个句型的大盒子,加上一定数量的隔板,划分为n个小盒子。

给某点坐标,判断该点是在哪个小盒子的范围内。

 

思路:叉积判断点是在隔板的哪一侧,二分搜索逐渐缩小范围。

 

#include <iostream> using namespace std; int count[5005]; struct Node { __int64 x,y; }; struct Edge { Node up; Node low; }boundary[5005]; inline __int64 CrossMutiply(Node p1,Node p2,Node p3) { return (p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x); } int n,m; __int64 x1,x2; Node upper_left,lower_right,temp; void Add(Node& p) { int first=0,end=n+1,mid; while(end-first>1) { mid=(first+end)/2; if(CrossMutiply(boundary[mid].low,boundary[mid].up,p)>0) end=mid; else first=mid; } count[first]++; } int main() { while(scanf("%d",&n)&&n) { scanf("%d%I64d%I64d%I64d%I64d",&m,&upper_left.x,&upper_left.y,&lower_right.x,&lower_right.y); boundary[0].up.x=boundary[0].low.x=0; boundary[n+1].up.x=boundary[n+1].low.x=lower_right.x; for(int i=0;i<=n+1;i++) { boundary[i].low.y=lower_right.y; boundary[i].up.y=upper_left.y; } for(int i=1;i<=n;i++) { scanf("%I64d%I64d",&x1,&x2); boundary[i].up.x=x1; boundary[i].low.x=x2; } memset(count,0,sizeof(count)); for(int i=0;i<m;i++) { scanf("%I64d%I64d",&temp.x,&temp.y); Add(temp); } for(int i=0;i<=n;i++) { printf("%d: %d/n",i,count[i]); } printf("/n"); } return 0; }

 

 

你可能感兴趣的:(struct)