题意:
给出一个矩形范围,给出n条线段,这n条线段一定与矩形上下边界相交且互不相交,将矩形分成n+1个划分。给出m个玩具的坐标。求每个划分放的玩具数,玩具保证不会在线段和左右边界上。
分析:
判断点是否在两条直线中间,利用叉积,如果在两条直线间,必定会有两个叉积一个小于0,一个大于0(不能把相乘小于0作为判断条件)
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=5000+5; int cnt[maxn]; struct Point { int x,y; Point() {}; Point(int xx,int yy) { x=xx; y=yy; } } Up[maxn],Lp[maxn],toys[maxn]; int crs_prdct(Point a,Point b) { return a.x*b.y-b.x*a.y; } Point vct(Point a,Point b) { return Point(a.x-b.x,a.y-b.y); } int main() { // freopen("in.txt","r",stdin); int n,m,x1,y1,x2,y2; while(scanf("%d",&n),n) { memset(cnt,0,sizeof(cnt)); scanf("%d",&m); scanf("%d%d",&x1,&y1); scanf("%d%d",&x2,&y2); Up[0]=Point(x1,y1); Up[n+1]=Point(x2,y1); Lp[0]=Point(x1,y2); Lp[n+1]=Point(x2,y2); for(int i=1; i<=n; i++) { int Ui,Li; scanf("%d%d",&Ui,&Li); Up[i]=Point(Ui,y1); Lp[i]=Point(Li,y2); } for(int i=0; i<m; i++) scanf("%d%d",&toys[i].x,&toys[i].y); for(int i=0; i<m; i++) { Point vct1,vct2,vct3,vct4; for(int j=0;j<=n; j++) { vct1=vct(Lp[j],toys[i]); vct2=vct(Up[j],toys[i]); vct3=vct(Lp[j+1],toys[i]); vct4=vct(Up[j+1],toys[i]); if(crs_prdct(vct1,vct2)<0 && crs_prdct(vct3,vct4)>0) { cnt[j]++; break; } } } for(int i=0;i<=n;i++) printf("%d: %d ",i,cnt[i]); puts(""); } return 0; }