zoukankan      html  css  js  c++  java
  • [POJ 3788] Interior Points of Lattice Polygons

    同swustoj 169
    Interior Points of Lattice Polygons
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 229   Accepted: 152

    Description

    lattice point is a point with integer coordinates. A lattice polygon is a polygon with all vertices lattice points. 



    The lattice points on the boundary of the polygon are boundary points (open dots in the figure above) and the points inside and not on the polygon are interior points (filled in dots in the figure above). 

    A polygon is convex if any line segment between two points of the polygon is inside (or on the boundary of) the polygon. Equivalently, the interior angle at each polygon vertex is less than 180 degrees. Note that any line between two points inside (and not on the boundary of) the polygon is entirely inside (and not on the boundary of) the polygon. 

    The interior points of a convex lattice polygon on any horizontal line form a single segment from a leftmost point to a rightmost point (which may be the same). Note that there may be no interior points (A), or only one (B), or isolated points (C) as shown in the figures below. 



    Write a program that reads the vertices of a convex lattice polygon in standard order and outputs the interior points as a list of horizontal line segments. The vertices of a lattice polygon are in standard order if: 
    a) The first vertex is the one with the largest y value. If two vertices have the same y value, the one with the smaller x value is the first. 
    b) Vertices are given in clockwise order around the polygon.

    Input

    The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that follow. The first line of each data set contains the data set number, followed by a space, followed by a decimal integer giving the number vertices N, (3 ≤ N ≤ 50), of the polygon. The remaining lines in the data set contain the vertices, one per line in standard order. Each line contains the decimal integer x coordinate, a space and the decimal integer y coordinate.

    Output

    For each data set there are multiple lines of output. The first line contains a decimal integer giving the data set number followed by a single space, followed by a decimal integer giving the number of horizontal lines which contain interior points (this may be zero (0) or more). The lines of interior points, if any, follow, one per line in order of decreasing y value. Each line contains the decimal integer y coordinate, a single space and the decimal integer x coordinate of the left most point, a single space and the decimal integer x coordinate of the right most point.

    Sample Input

    6 
    1 8 
    5 10 
    8 9 
    11 6 
    10 2 
    6 0 
    1 1 
    0 4 
    2 8 
    2 4 
    3 10 
    13 7 
    10 -3 
    0 0 
    3 3 
    1 3 
    3 1 
    1 1 
    4 3 
    1 4 
    4 1 
    1 1 
    5 4 
    0 6 
    2 3 
    3 0 
    1 3 
    6 6 
    1 3 
    3 3 
    4 2 
    3 1 
    1 1 
    0 2

    Sample Output

    1 9
    9 4 7
    8 3 8
    7 2 9 
    6 2 10 
    5 1 10 
    4 1 10 
    3 1 10 
    2 1 9 
    1 2 7 
    2 12 
    9 3 6 
    8 3 9 
    7 3 12 
    6 2 12 
    5 2 12 
    4 2 12 
    3 1 11 
    2 1 11 
    1 1 11 
    0 1 10 
    -1 4 10 
    -2 7 10 
    3 0 
    4 1 
    2 2 2 
    5 2 
    4 1 1 
    2 2 2 
    6 1 
    2 1 3

    题意:给出一个凸多边形,求在其内部的格点

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define PI acos(-1.0)
    #define EPS 1e-10
    #define N 1010
    
    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){}
        Point operator - (Point p){
            return Point(x-p.x,y-p.y);
        }
        double operator * (Point p){
            return x*p.x+y*p.y;
        }
        double operator ^ (Point p){
            return x*p.y-y*p.x;
        }
        bool operator < (const Point &p)const
        {
            if(y!=p.y) return y>p.y;
            return x<p.x;
        }
    };
    struct Line
    {
        Point s,e;
        Line (){}
        Line (Point s,Point e):s(s),e(e){}
    };
    bool PointOnSeg(Line l,Point p)
    {
        return dcmp((l.s-p)^(l.e-p))==0 && dcmp((l.s-p)*(l.e-p))<=0;
    }
    int PointInConvexPoly(Point p[],Point q,int n)
    {
        for(int i=0;i<n;i++){
            if(dcmp((p[i]-q)^(p[(i+1)%n]-q))>0) return -1;
            if(PointOnSeg(Line(p[i],p[(i+1)%n]),q)) return 0;
        }
        return 1;
    }
    int main()
    {
        int n;
        int T,iCase;
        Point p[1010];
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&iCase,&n);
            double mxx,mix,mxy,miy;
            mix=miy=INF;
            mxx=mxy=-INF;
            for(int i=0;i<n;i++){
                scanf("%lf%lf",&p[i].x,&p[i].y);
                mix=min(mix,p[i].x);
                mxx=max(mxx,p[i].x);
                miy=min(miy,p[i].y);
                mxy=max(mxy,p[i].y);
            }
            int k=0;
            Point q[1010];
            for(int i=mix;i<=mxx;i++){
                for(int j=miy;j<=mxy;j++){
                    if(PointInConvexPoly(p,Point(i,j),n)==1){
                        q[k++]=Point(i,j);
                    }
                }
            }
            if(k==0){
                printf("%d 0
    ",iCase);
                continue;
            }
            sort(q,q+k);
            int i,j,cnt=1;
            for(i=1;i<k;i++) if(q[i].y!=q[i-1].y) cnt++;
            printf("%d %d
    ",iCase,cnt);
            for(i=0;i<k;i++){
                printf("%g %g",q[i].y,q[i].x);
                for(j=i+1;j<k;j++){
                    if(q[j].y!=q[i].y) break;
                }
                printf(" %g",q[j-1].x);
                printf("
    ");
                i=j-1;
            }
        }
        return 0;
    }
  • 相关阅读:
    .NET旋转PDF并保存旋转结果到文件
    C#的抽象类和接口的区别,在什么时候使用才合适?
    [转]SQL Server中多行多列连接成为单行单列
    VBS脚本COPY指定日期文件及文件夹
    eval同时绑定两个值:通过String.Format给超链接中的两个参数赋值
    How to recover SA password on Microsoft SQL Server 2008 R2
    [转]asp.net 前台绑定后台变量方法总结:<%= %> 和<%# %>的区别
    Js得到radiobuttonlist选中值的两种方式
    Ameriscan增加一个新的client:AP_CONSO
    命令行处理pdf的利器:PDFTK.exe
  • 原文地址:https://www.cnblogs.com/hate13/p/4598259.html
Copyright © 2011-2022 走看看