poj 2398

来源:互联网 发布:fs软件像ppt的软件 编辑:程序博客网 时间:2024/04/29 06:01

叉积+二分

通过叉积来判断点在线段的某侧,找到在点右侧的最左边的边,即可判断点在第几个格子内,可以通过二分来优化查询速度

#include <iostream>#include <algorithm>#include <cstdio>using namespace std;const int maxn=1000+10;int n,m,x1,y1,x2,y2;struct segment{int loc1,loc2;};segment s[maxn];int c[maxn],res[maxn];bool cmp(segment a,segment b) { return a.loc1<b.loc1; }int cross(segment ts,int x,int y){int vx1=ts.loc1-ts.loc2,vy1=y1-y2,vx2=x-ts.loc1,vy2=y-y1;return vx1*vy2-vy1*vx2;}int main(){while(scanf("%d",&n)&&n){scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);int i;for(i=1;i<=n;i++)scanf("%d%d",&s[i].loc1,&s[i].loc2);s[0].loc1=x1;s[0].loc2=x1;s[n+1].loc1=x2;s[n+1].loc2=x2;sort(s,s+n+2,cmp);int x,y;memset(c,0,sizeof(c));memset(res,0,sizeof(res));for(i=0;i<m;i++){scanf("%d%d",&x,&y);int high=n+2,low=0,mid;while(low<high)//找到在点右侧的最左边的边,即可判断点在第几个格子内{mid=low+(high-low)/2;if(cross(s[mid],x,y)>0) high=mid;else low=mid+1;}c[low]++;}for(i=1;i<=n+1;i++) res[c[i]]++;printf("Box\n");for(i=1;i<=n+1;i++)if(res[i]) printf("%d: %d\n",i,res[i]);}return 0;}


原创粉丝点击