POJ 2398 Toy Storage(判定点在四边形内)

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;
}

你可能感兴趣的:(Algorithm,算法,ACM,计算几何)