poj2398叉积之点定位+二分

  问题说白了就是:看给定的点在哪两个线段之间。根据题目的描述,给定的点要么在线段左边,要么右边,所以需做一个叉积,来判定点与两条线段的位置关系(具体如下面的FindBelongBinIndex()函数描述)。

  因为线段是排好序的了,所以可以二分查找。

 

#include <iostream>
#include <algorithm>
using namespace std;

struct Point2D
{
	Point2D()
	{
		x=0.0f;
		y=0.0f;
	}
	Point2D(double tx,double ty)
	{
		x=tx;
		y=ty;
	}

	double x,y;
};

//Return the crossproduct of vec1*vec2
double CrossProduct(Point2D vec1,Point2D vec2)
{
	return vec1.x*vec2.y-vec1.y*vec2.x;
}

//Comparision Function
bool IntLessComparision(int a,int b)
{
	return a<b;
}

bool PointXComparision(Point2D a,Point2D b)
{
	return a.x<=b.x;
}

//Find the index of the bin which the toy belongs to.
inline int FindBelongBinIndex(Point2D upPos[],Point2D lowPos[],Point2D toyPos, int nBin )
{
	int low=0,high=nBin-1;
	while(low<=high)
	{
		int mid=(low+high)/2;
		//test midth bin
		double crossLeft=CrossProduct( Point2D(lowPos[mid].x-upPos[mid].x,lowPos[mid].y-upPos[mid].y), Point2D(toyPos.x-upPos[mid].x,toyPos.y-upPos[mid].y));
		double crossRight=CrossProduct( Point2D(lowPos[mid+1].x-upPos[mid+1].x,lowPos[mid+1].y-upPos[mid+1].y), Point2D(toyPos.x-upPos[mid+1].x,toyPos.y-upPos[mid+1].y));
		if(crossLeft>0 && crossRight<0)
		{
			return mid;
		}
		else if(crossLeft<0)
		{
			high=mid-1;
			continue;
		}
		else if(crossRight>0)
		{
			low=mid+1;
			continue;
		}
	}
	return -1;
}

int main()
{
	int nCardboardNumber;
	int nBinNumber;
	int nToyNumber;
	//Store the i cardboard's up x value and low x value.
	Point2D upPos[5005];
	Point2D lowPos[5005];
	//The up and low y value of toy box. 
	double lowY;
	double upY;
	//The toy number of each bin
	int ToyNumberOfBin[5005];
	//The positions of toys
	Point2D toyPosition[5005];

	scanf("%d",&nCardboardNumber);
	while(nCardboardNumber!=0)
	{
		memset(ToyNumberOfBin,0,sizeof(ToyNumberOfBin) );
		nCardboardNumber+=2;//With the first and last cardboard
		nBinNumber=nCardboardNumber-1;//The number of the bin
		scanf("%d",&nToyNumber);
		scanf("%lf%lf%lf%lf",&upPos[0].x,&upPos[0].y,&lowPos[nCardboardNumber-1].x,&lowPos[nCardboardNumber-1].y);

		lowPos[0].x=upPos[0].x;
		lowPos[0].y=lowPos[nCardboardNumber-1].y;

		upPos[nCardboardNumber-1].x=lowPos[nCardboardNumber-1].x;
		upPos[nCardboardNumber-1].y=upPos[0].y;


		for(int i=1;i<nCardboardNumber-1;i++)
		{
			scanf("%lf%lf",&upPos[i].x,&lowPos[i].x);
			upPos[i].y=upPos[i-1].y;
			lowPos[i].y=lowPos[i-1].y;
		}
		sort(upPos,upPos+nCardboardNumber,PointXComparision);
		sort(lowPos,lowPos+nCardboardNumber,PointXComparision );

		for(int i=0;i<nToyNumber;i++)
		{
			scanf("%lf%lf",&toyPosition[i].x,&toyPosition[i].y);
			int index=FindBelongBinIndex(upPos,lowPos,toyPosition[i],nBinNumber);
			if(index==-1)
			{
				break;
				printf("Bounding Error/n");
			}
			else ToyNumberOfBin[index]++;
		}

		sort(ToyNumberOfBin,ToyNumberOfBin+nBinNumber,IntLessComparision);

		printf("Box\n");
		
		int k=0;
		while(ToyNumberOfBin[k]==0)
			k++;

		int tCount=1;
		while(k<nBinNumber)
		{
			if(k<nBinNumber-1 && ToyNumberOfBin[k]==ToyNumberOfBin[k+1])
			{
				tCount++;
			}
			else
			{
				printf("%d: %d\n",ToyNumberOfBin[k],tCount);
				tCount=1;
			}
			k++;
		}

		scanf("%d",&nCardboardNumber);
	}
	return 0;
}


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值