POJ 2398 Toy Storage(判定点在四边形内)
http://poj.org/problem?id=2398
题意:
有一个平行于坐标轴的长矩形,被n块木板分成了n+1个包间.然后给你一些点的坐标,要你从小到大输出t:x. 其中t:x表示包含t个点的隔间有x个.t按从小到大排序.
分析:
本题与POJ2318基本一样,
http://blog.youkuaiyun.com/u013480600/article/details/39909563
不过输出格式不同且输入数据的每个木板的x坐标并没有按顺序给出,所以这里我们需要对所有输入木板的两个x坐标对进行排序.
且我们只需要对木板的第1维的x坐标排序即可.因为木板不会相交叉,所以它们的任意一维x坐标必然都是有序的.
对木板排序之后,之后按顺序构造所有的隔间4边行,然后判断每个点是否在一个4边行内即可. 最终输出对应结果.
AC代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const double eps=1e-10;
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
return x<0?-1:1;
}
struct Point
{
double x,y;
Point(){}
Point(double x,double y):x(x),y(y){}
};
typedef Point Vector;
Vector operator-(Point A,Point B)
{
return Vector(A.x-B.x,A.y-B.y);
}
double Dot(Vector A,Vector B)
{
return A.x*B.x+A.y*B.y;
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}
bool InSegment(Point P,Point A,Point B)
{
return dcmp( Cross(A-B,P-A) )==0 && dcmp( Dot(A-P,B-P) )<=0;
}
//poly中的点按顺时针排序,所以内点应该在所有边右边
bool PointInPolygen(Point p,Point* poly)
{
for(int i=0;i<4;++i)
if( dcmp(Cross(poly[(i+1)%4]-poly[i], p-poly[i]))>0 ) return false;
return true;
}
const int maxn=1000+10;
struct Node//木板的两个x坐标
{
double x1,x2;
Node(){}
Node(double x1,double x2):x1(x1),x2(x2){}
bool operator<(const Node &rhs)const
{
return x1<rhs.x1 || (x1==rhs.x1 && x2<rhs.x2);
}
}nodes[maxn];
Point poly[maxn][4];
int main()
{
int n,m;
double x1,y1,x2,y2;
while(scanf("%d",&n)==1 && n)
{
scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);
nodes[0]=Node(x1,x1);
nodes[n+1]=Node(x2,x2);
for(int i=1;i<=n;++i)
scanf("%lf%lf",&nodes[i].x1,&nodes[i].x2);
sort(nodes,nodes+n+2);
for(int i=0;i<=n;++i)
{
poly[i][0]=Point(nodes[i].x1,y1);
poly[i][1]=Point(nodes[i+1].x1,y1);
poly[i][2]=Point(nodes[i+1].x2,y2);
poly[i][3]=Point(nodes[i].x2,y2);
}
int ans[maxn];//ans[i]==x表 第i个方格有x个点
memset(ans,0,sizeof(ans));
for(int i=1;i<=m;++i)
{
Point p;
scanf("%lf%lf",&p.x,&p.y);
for(int j=0;j<=n;++j)
if(PointInPolygen(p,poly[j]))//判断点是否在4边形内
{
ans[j]++;
break;
}
}
int num[maxn];//num[i]==x表 装有i个点的隔间有x个
memset(num,0,sizeof(num));
for(int i=0;i<=n;++i)if(ans[i])
num[ans[i]]++;
printf("Box\n");
for(int i=1;i<=m;++i)if(num[i])
printf("%d: %d\n",i,num[i]);
}
return 0;
}