POJ 2398 Toy Storage(判定点在四边形内)
http://poj.org/problem?id=2398
题意:
有一个平行于坐标轴的长矩形,被n块木板分成了n+1个包间.然后给你一些点的坐标,要你从小到大输出t:x. 其中t:x表示包含t个点的隔间有x个.t按从小到大排序.
分析:
本题与POJ2318基本一样,
http://blog.csdn.net/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; }