• [POJ][1228][Grandpa's Estate]


    题目:http://poj.org/problem?id=1228

    题意:给定一些点,求能否确定一个凸包。如果在这些点中求出的凸包的每一条边都至少有三个点(包括顶点),则这个凸包是确定的。

        注意一条直线或点数n<5时应输出NO。

    View Code
    #include <stdio.h>
    #include
    <math.h>
    #include
    <string.h>
    #include
    <iostream>
    #include
    <algorithm>

    using namespace std;
    const double eps = 1e-8;
    const double pi = acos(-1.0);

    typedef
    struct
    {
    double x, y;
    }cpoint;

    double sqr(double x) {return x*x;}

    double dcmp(double x)
    {
    if(x < -eps) return -1; else return x > eps;
    }

    double cross(cpoint p0, cpoint p1, cpoint p2)
    {
    return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
    }

    double dot(cpoint p0, cpoint p1, cpoint p2)
    {
    return (p1.x - p0.x) * (p2.x - p0.x) + (p1.y - p0.y) * (p2.y - p0.y);
    }

    double dis(cpoint p1, cpoint p2)
    {
    return sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y));
    }

    double dissqr(cpoint p1, cpoint p2)
    {
    return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
    }

    int PointEqual(const cpoint p1, const cpoint p2)
    {
    return dcmp(p1.x - p2.x) == 0 && dcmp(p1.y - p2.y) == 0;
    }

    int PointOnSegment(cpoint p0, cpoint p1, cpoint p2)
    {
    return dcmp(cross(p0, p1, p2)) == 0 && dcmp(dot(p0, p1, p2)) <= 0;
    }

    cpoint bp;

    int PolarCmp(const cpoint &p1, const cpoint &p2)
    {
    int u = dcmp(cross(bp, p1, p2));
    return u > 0 || (u == 0 && dcmp(dissqr(bp, p1)-dissqr(bp, p2)) < 0);
    }

    int PointInPolygon(cpoint cp, cpoint p[], int n)
    {
    int i, k, d1, d2, wn = 0;
    double sum = 0;
    p[n]
    = p[0];
    for (int i = 0; i < n; i++)
    {
    if (PointOnSegment(cp, p[i], p[i+1])) return 2;
    k
    = dcmp(cross(p[i], p[i+1], cp));
    d1
    = dcmp(p[i+0].y - cp.y);
    d2
    = dcmp(p[i+1].y - cp.y);
    if (k > 0 && d1 <= 0 && d2 > 0) wn++;
    if (k < 0 && d2 <= 0 && d1 > 0) wn--;
    }
    return wn != 0;
    }

    void graham(cpoint pin[], int n, cpoint ch[], int &m)
    {
    int i, j, k, u, v;
    memcpy(ch, pin, n
    *sizeof(cpoint));
    for (i = k = 0; i < n; i++)
    {
    u
    = dcmp(ch[i].x - ch[k].x);
    v
    = dcmp(ch[i].y - ch[k].y);
    if (v < 0 || (v == 0 && u < 0)) k = i;
    }
    bp
    = ch[k];
    sort(ch, ch
    + n, PolarCmp);
    n
    = unique(ch, ch + n, PointEqual) - ch;
    if (n <= 1) {m = n; return ;}
    if (dcmp(cross(ch[0], ch[1], ch[n-1])) == 0)
    {
    m
    = 2; ch[1] = ch[n-1]; return ;
    }
    ch[n
    ++] = ch[0];
    for (i = 1, j = 2; j < n; j++)
    {
    while (i > 0 && dcmp(cross(ch[i-1], ch[i], ch[j])) <= 0) i--;
    ch[
    ++i] = ch[j];
    }
    m
    = i;
    }

    double PolygononArea(cpoint p[], int n)
    {
    if (n < 3) return 0;
    double s = p[0].y * (p[n-1].x - p[1].x);
    for (int i = 1; i<n; i++)
    {
    s
    += p[i].y * (p[i-1].x - p[(i+1) % n].x);
    }
    return fabs(s / 2.0);
    }

    double LengthOfPolygon(cpoint p[], int m)
    {
    double length = 0;
    for (int i=0; i<m; i++)
    {
    length
    += dis(p[i], p[(i+1)%m]);
    }
    return length;
    }

    cpoint kingdom[
    1005];
    cpoint polygon_kingdom[
    1005];
    int m, v[1005], segment[1005];

    int main()
    {
    //freopen("D:/a.txt", "r", stdin);
    int ncase, n;
    scanf(
    "%d", &ncase);
    for (int k=0; k<ncase; k++)
    {
    memset(v,
    0, sizeof(v));
    memset(segment,
    0, sizeof(segment));
    scanf(
    "%d", &n);
    for (int i=0; i<n; i++)
    {
    scanf(
    "%lf%lf", &kingdom[i].x, &kingdom[i].y);
    }
    graham(kingdom, n, polygon_kingdom, m);
    int stop = 0;
    for (int i=0; i<n; i++)
    {
    if (PointInPolygon(kingdom[i], polygon_kingdom, m) == 1)
    {
    printf(
    "NO\n");
    stop
    = 1;
    break;
    }
    }
    if (stop) continue;
    for (int i=0; i<m; i++)
    {
    for (int j=0; j<n; j++)
    {
    if (v[j]) continue;
    if (PointEqual(kingdom[j], polygon_kingdom[i])) {v[j]=1;continue;}
    if (PointEqual(kingdom[j], polygon_kingdom[(i+1)%m])) {v[j]=1;continue;}
    if (PointOnSegment(kingdom[j], polygon_kingdom[(i+1)%m], polygon_kingdom[i])){segment[i]=1; continue;}
    }
    }
    int sum = 0;
    for (int i=0; i<m; i++)
    {
    sum
    += segment[i];
    }
    if (n < 6){printf("NO\n"); continue;}
    if (m <= 2){printf("NO\n"); continue;}
    if (m == sum) printf("YES\n");
    else printf("NO\n");
    }
    return 0;
    }
  • 相关阅读:
    mac安装完anaconda后,环境变量设置
    axios如何发送Basic Auth
    Django自带认证系统邮件模板自定义
    Ajax与Flask传值的跨域问题
    一道XXE漏洞和SSRF结合的题目
    如何分多次Pull requests
    如何使用C#写个多简单文档编辑器
    如何用Tkinter写个计算器
    LCTF2017学到的姿势
    Python 学习之路
  • 原文地址:https://www.cnblogs.com/nigel0913/p/2172395.html
Copyright © 2020-2023  润新知