先按照每个隔板上端x的大小从左到右排序

排好之后用二分找到每个玩具在第i个隔板的右边,玩具就在i+1区域

再统计有i个玩具的区域有多少个(i>0)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e3+10;
//Point定义
const double eps=1e-8;
const double PI=acos(-1.0);
int sgn(double x)
{
	if(fabs(x)<eps) return 0;
	if(x<0) return -1;
	else return 1;
}
struct Point
{
	double x,y;
	Point(){}
	Point(double _x,double _y)
	{
		x=_x;y=_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;
	}
	///绕原点旋转角度B(弧度值),后x,y的变化 
	void transXY(double B)
	{
		double tx=x,ty=y;
		x=tx*cos(B)-ty*sin(B);
		y=tx*sin(B)+ty*cos(B);
	}
};
//两点描述直线
struct Line
{  
	Point s,e;  
 	Line(){}  
 	Line(Point _s,Point _e)  {   s = _s;e = _e;  }  
 	bool operator < (const Line &u) const
 	{
 		return s.x<u.s.x;
 	}
}L[N];
bool is_right(Point a,Line b)
{
	double ly=b.s.y-b.e.y;
	double lx=b.s.x-b.e.x;
	double k=(a.y-b.e.y)/ly;
	double x0=b.e.x+k*lx;
	if(x0>a.x) return false;
	return true;
}
int ans[N],num[N];
int main()
{
	int n,m;
	double x1,x2,y1,y2;
	Point u;
	while(~scanf("%d",&n)&&n)
	{
		scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);
		for(int i=0;i<n;i++)
		{
			L[i].s.y=y1;
			L[i].e.y=y2;
			scanf("%lf%lf",&L[i].s.x,&L[i].e.x);
		}
		sort(L,L+n);
		memset(ans,0,sizeof(ans));
		memset(num,0,sizeof(num));
		for(int i=0;i<m;i++)
		{
			scanf("%lf%lf",&u.x,&u.y);
			int t=0;
			int l=0,r=n-1;
			while(l<r)
			{
				int m=(l+r)>>1;
				if(is_right(u,L[m])) t=m+1,l=m+1;
				else r=m;
			}
			if(is_right(u,L[r])) t=r+1;
			ans[t]++;
		}
		for(int i=0;i<=n;i++) num[ans[i]]++;
		printf("Box\n");
		for(int i=1;i<=n;i++)
			if(num[i])
			printf("%d: %d\n",i,num[i]);
	}
	return 0;
}

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐