POJ 2318 TOYS (点与线段关系)

一个玩具箱被n个挡板分成n+1快,挡板不会互相交叉。将m个玩具扔进去,求分别被扔进了哪个区域。

主要算法就是判断点与线段的关系,排序后从左往右依此判别即可。

//Memory: 480K		
//Time: 485MS
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
struct POINT				//点
{
	double x,y;
	POINT():x(0),y(0){};
    POINT(double _x, double _y):x(_x),y(_y){};
};
struct LINESEG			//线段
{ 
	POINT s; 
	POINT e; 
	LINESEG(POINT a, POINT b) { s=a; e=b;} 
	LINESEG() { } 
};
double relation_lr(POINT p,LINESEG l)   //return<0 p在l左侧  return>0 p在l右侧
{
	double a,b,c;
	a=l.e.y-l.s.y;
	b=l.s.x-l.e.x;
	c=l.e.x*l.s.y-l.s.x*l.e.y;
	return (a*p.x+b*p.y+c);
} 
bool cmpl(LINESEG l1,LINESEG l2)
{
	if(l1.s.x==l2.s.x)
		return l1.e.x<l2.e.x;
	return l1.s.x<l2.s.x;
}
bool cmpp(POINT p1,POINT p2)
{
	return p1.x<p2.x;
}
int main()
{
	POINT p[5005];
	LINESEG l[5005];
	double x1,y1,x2,y2;
	int n,m;
	int num[5005];
	int flag=true;
	while(cin>>n && n)
	{
		cin>>m>>x1>>y1>>x2>>y2;
		l[0].s.x=l[0].e.x=x1;
		l[0].s.y=l[n+1].s.y=y2;
		l[0].e.y=l[n+1].e.y=y1;
		l[n+1].s.x=l[n+1].e.x=x2;
		int i,j;
		for(i=0;i<=n;i++)
			num[i]=0;
		for(i=1;i<=n;i++)
		{
			cin>>l[i].e.x>>l[i].s.x;
			l[i].e.y=y1;
			l[i].s.y=y2;
		}
		for(i=1;i<=m;i++)
			cin>>p[i].x>>p[i].y;
		sort(l,l+n+1,cmpl);
		sort(p+1,p+m+1,cmpp);
		i=0;j=1;
		while(i<=n)
		{
			if(relation_lr(p[j],l[i+1])>0)
			{
				i++;
			}
			else if(relation_lr(p[j],l[i])>0)
			{
				num[i]++;
				j++;
			}
			else if(relation_lr(p[j],l[i])<0)
			{
				i--;
			}
			if(j>m)
				break;
		}
		if(!flag)
			cout<<endl;
		for(i=0;i<=n;i++)
			cout<<i<<": "<<num[i]<<endl; 
		flag=false;
	}
	return 0;
}

你可能感兴趣的:(POJ 2318 TOYS (点与线段关系))