题目链接:点击查看
题目大意:给出一个盒子,由n条互不相交的线段分割为n+1个空格,现在有m个玩具的坐标,现在问每个空格内有多少个玩具
题目分析:利用叉积的性质判断点在直线的哪一侧:
以点在直线左侧为例,对于一个点来说,n条线段就具有了单调性,以此二分找到该点右边的直线,则就确定了当前点所在的空格了
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int N=5e3+100;
int ans[N];
struct Point{
double x,y;
Point(){}
Point(double _x,double _y){
x = _x;
y = _y;
}
void input(){
scanf("%lf%lf",&x,&y);
}
Point operator -(const Point &b)const{
return Point(x-b.x,y-b.y);
}
//叉积
double operator ^(const Point &b)const{
return x*b.y - y*b.x;
}
//点积
double operator *(const Point &b)const{
return x*b.x + y*b.y;
}
}point[N];
struct Line{
Point s,e;
Line(){}
Line(Point _s,Point _e){
s = _s;
e = _e;
}
}line[N];
int xmult(Point p0,Point p1,Point p2)// ans>0左边 ans<0右边
{
return (p1-p0)^(p2-p0);
}
int main()
{
// freopen("input.txt","r",stdin);
// ios::sync_with_stdio(false);
int n,m,x1,y1,x2,y2;
while(scanf("%d",&n)!=EOF&&n)
{
scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
for(int i=0;i<n;i++)
{
int u,l;
scanf("%d%d",&u,&l);
line[i]=Line(Point(u,y1),Point(l,y2));
}
line[n]=Line(Point(x2,y1),Point(x2,y2));
memset(ans,0,sizeof(ans));
while(m--)
{
Point p;
p.input();
int l=0,r=n,mark;
while(l<=r)
{
int mid=l+r>>1;
if(xmult(p,line[mid].s,line[mid].e)<0)
{
mark=mid;
r=mid-1;
}
else
l=mid+1;
}
ans[mark]++;
}
for(int i=0;i<=n;i++)
printf("%d: %d\n",i,ans[i]);
printf("\n");
}
return 0;
}