想看更多的解题报告: http://blog.youkuaiyun.com/wangjian8006/article/details/7870410
转载请注明出处:http://blog.youkuaiyun.com/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;
}