想看更多的解题报告: 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; }