题目大意:
n块玩具箱隔板 m个玩具落地点 给定玩具箱的左上和右下两个端点
接下来给定n块隔板的上点的x和下点的x(因为y就是玩具箱的上下边缘)
接下来给定m个玩具落地点
输出n+1个区域各有的玩具数量
只要判断一下玩具落地点对于n条直线的相对位置即可
当它位于某条直线的左侧时 说明它位于当前直线内的区域
#include <cstdio> #include <cmath> #include <string.h> #include <algorithm> using namespace std; const double eps=1e-10; double add(double a,double b) { if(abs(a+b)<eps*(abs(a)+abs(b))) return 0; return a+b; } struct P { double x,y; P(){}; P(double _x,double _y):x(_x),y(_y){}; P operator - (P p) { return P(add(x,-p.x),add(y,-p.y)); }; P operator + (P p) { return P(add(x,p.x),add(y,p.y)); }; P operator * (double d) { return P(x*d,y*d); }; double dot (P p) { return add(x*p.x,y*p.y); }; double det (P p) { return add(x*p.y,-y*p.x); }; }st,ed,a[5005],b[5005],toy; int ans[5005]; int n, m; int main() { while(~scanf("%d",&n)) { if(n==0) break; scanf("%d%lf%lf%lf%lf",&m,&st.x,&st.y,&ed.x,&ed.y); for(int i=0;i<n;i++) { scanf("%lf%lf",&a[i].x,&b[i].x); a[i].y=st.y, b[i].y=ed.y; } a[n].x=ed.x, a[n].y=st.y; b[n].x=ed.x, b[n].y=ed.y; // 加入玩具箱的右边缘 memset(ans,0,sizeof(ans)); for(int i=0;i<m;i++) { scanf("%lf%lf",&toy.x,&toy.y); int k=0; while((a[k]-toy).det(b[k]-toy)>0) k++; /* 判断直线 直到toy在直线的左侧 >0说明 (a[k]-toy)在(b[k]-toy)顺时针方向 即 toy在直线a[k]b[k]的右侧 */ ans[k]++; } for(int i=0;i<=n;i++) printf("%d: %d\n",i,ans[i]); printf("\n"); } return 0; }