Description
Input
Output
Sample Input
5 6 0 10 60 0 3 1 4 3 6 8 10 10 15 30 1 5 2 1 2 8 5 5 40 10 7 9 4 10 0 10 100 0 20 20 40 40 60 60 80 80 5 10 15 10 25 10 35 10 45 10 55 10 65 10 75 10 85 10 95 10 0
Sample Output
0: 2 1: 1 2: 1 3: 1 4: 0 5: 1 0: 2 1: 2 2: 2 3: 24: 2
给你n条线把一个长方形分割成n+1个空间
给你m个点让你判断这m个点分别在哪些空间中并统计个数
一开始想复杂了 想通过判断点是否在这n+1个4边形中
后来发现只要找到离每个点右边最近的那条线段的编号就可以确定该点属于哪个空间了
这里利用叉积的知识 对于向量 P和Q
P*Q>0 则P在Q顺时针方向
P*Q<0 则P在Q逆时针方向
P*Q=0 P与Q共线 不一定同向
连接 点 p和 每条线段的下面那个点形成向量就可以通过叉积判断点对于不同线段的位置
这里我们采取二分线段来确定点在的区域
ACcode:
#include <cstring> #include <cstdio> #define maxn 5050 struct Point{ int x,y; Point (){} Point(int _x,int _y){ x=_x; y=_y; } }p[maxn]; struct Line{ Point s,e; Line(){} Line(Point _s,Point _e){ s=_s; e=_e; } }my[maxn]; int ans[maxn]; int multi(Point p1,Point p2,Point p0){ return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } int main(){ int n,m,x1,y1,x2,y2; while(~scanf("%d",&n),n){ scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2); for(int i=0;i<n;++i){ int a,b; scanf("%d%d",&a,&b); my[i]=Line(Point(a,y1),Point(b,y2)); } my[n]=Line(Point(x2,y1),Point(x2,y2)); memset(ans,0,sizeof(ans)); for(int i=1;i<=m;++i){ int x,y; scanf("%d%d",&x,&y); Point tmp=Point(x,y); int l=0,r=n,id; while(l<=r){ int mid=(l+r)>>1; if(multi(my[mid].s,my[mid].e,tmp)<0){ id=mid; r=mid-1; } else l=mid+1; } ans[id]++; } for(int i=0;i<=n;++i) printf("%d: %d\n",i,ans[i]); putchar('\n'); } return 0; }