poj2398 - Toy Storage

                                  想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
                                  转载请注明出处:http://blog.csdn.net/wangjian8006

题目大意:意思与poj2318一样,只不过给出的线段不再是有序的,所以需要排序,

输出也有点不同,需要输出有玩具1-m个的区间有多少个

还有看了discuss说是会爆int,修改了一下类型,在2318的类上写了一个继承类来新增功能。

虽然代码比较长,但是还是慢慢熟悉用工程的方法来写代码吧.

/*题目大意:意思与2318一样,只不过给出的线段不再是有序的,所以需要排序,之后输出也有点不同,
还有看了discuss说是会爆int,在2318的类上写了一个继承类来新增功能。
虽然代码比较长,但是还是慢慢熟悉用工程的方法来写代码吧.
*/
#include <iostream>
#include <algorithm>
using namespace std;
#define _MAXL_ 5010

typedef long BoxType;

typedef struct{
	BoxType x, y;
}POINT;

typedef struct{
	POINT first,second;
}LINE;

class CBox{
protected:
	BoxType nTop,nLeft,nRight,nButtom;
	BoxType nCountLine;						//记录盒子里有多少条线
	LINE *pLine;						//记录线的信息
	BoxType *pRange;						//记录区间中的玩具有多少个
	BoxType Multi(POINT p1,POINT p2,POINT p0);			//叉积计算
public:
	CBox();
	virtual ~CBox();
	void SetBorder(BoxType top,BoxType left,BoxType right,BoxType buttom);		//设置盒子矩形坐标
	void AddLine(BoxType topx,BoxType buttomx);							//在盒子中增加一条线
	BoxType GetRange(BoxType val);								//得到某个区间中的玩具个数
	void SetToy(POINT toy);							//在盒子里放一个玩具
};

class CBoxTow:public CBox{
protected:
	BoxType *pRangeCount;
public:
	CBoxTow();
	virtual ~CBoxTow();
	void LinePer();							//将线段排序
	void CountRange();						//计算每个玩具个数的区间有多少个
	BoxType GetRangeCount(BoxType val);		//得到某个某个玩具个数的区间个数
};

CBox::CBox(){
	nCountLine = 0;
	pLine = new LINE[_MAXL_];
	pRange = new BoxType[_MAXL_];
	memset(pRange,0,sizeof(BoxType)*_MAXL_);
}

CBox::~CBox(){
	delete []pLine;
	delete []pRange;
}

void CBox::SetBorder(BoxType top,BoxType left,BoxType right,BoxType buttom){
	nTop = top;
	nLeft = left;
	nRight = right;
	nButtom = buttom;
}

void CBox::AddLine(BoxType topx,BoxType buttomx){
	pLine[nCountLine].first.x = topx;
	pLine[nCountLine].first.y = nTop;
	pLine[nCountLine].second.x = buttomx;
	pLine[nCountLine].second.y = nButtom;
	nCountLine++;
}

BoxType CBox::GetRange(BoxType val){
	return pRange[val];
}

BoxType CBox::Multi(POINT p1,POINT p2,POINT p0){
	return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}

void CBox::SetToy(POINT toy){			//利用二分查找,查找出该点在哪个区间
	int l, r, mid;
	l=0,r=nCountLine-1;
	while (l < r){
		mid = (l+r)>>1;
		if (Multi(toy, pLine[mid].first, pLine[mid].second) > 0) l = mid + 1;
		else r = mid;
	}  
	if (Multi(toy, pLine[l].first, pLine[l].second) < 0) pRange[l]++;
	else pRange[l+1]++;
}

CBoxTow::CBoxTow(){
	pRangeCount = new BoxType[_MAXL_];
	memset(pRangeCount,0,sizeof(BoxType)*_MAXL_);
}

CBoxTow::~CBoxTow(){
	delete []pRangeCount;
}

bool cmp(const LINE& a,const LINE &b){
	return a.first.x <= b.first.x;
}

void CBoxTow::LinePer(){
	sort(pLine,pLine+nCountLine,cmp);
}

void CBoxTow::CountRange(){
	int i;
	for(i = 0;i <= nCountLine;i++){
		pRangeCount[pRange[i]]++;
	}
}

BoxType CBoxTow::GetRangeCount(BoxType val){
	return pRangeCount[val];
}

int main(){
	BoxType i,fx,lx;
	POINT a,b;
	BoxType n,m;
	while(cin>>n && n){
		cin>>m>>a.x>>a.y>>b.x>>b.y;
		CBoxTow box;
		box.SetBorder(a.y,a.x,b.x,b.y);
		for(i = 0;i < n;i++){
			cin>>fx>>lx;
			box.AddLine(fx,lx);
		}

		box.LinePer();
		
		for(i = 0;i < m;i++){
			cin>>a.x>>a.y;
			box.SetToy(a);
		}

		box.CountRange();
		
		cout<<"Box"<<endl;
		for(i = 1;i <= m;i++){
			if(box.GetRangeCount(i)!=0)
				cout<<i<<": "<<box.GetRangeCount(i)<<endl;
		}
	}
	return 0;
}


 

 

你可能感兴趣的:(poj2398 - Toy Storage)