• [POJ] [1264] [SCUD Busters]


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

    一道凸包题,求导弹射中的凸包的面积之和。 

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

    cpoint kingdom[
    22][105];
    cpoint polygon_kingdom[
    22][105];
    int m[22], v[22];

    int main()
    {
    //freopen("D:/a.txt", "r", stdin);
    int n, top=0;
    memset(v,
    0, sizeof(v));
    while(scanf("%d", &n))
    {
    if (n == -1)
    {
    //printf("-------------n = -1-------\n");
    cpoint missile;
    while (scanf("%lf%lf", &missile.x, &missile.y)!=EOF)
    {
    for (int i=0; i<top; i++)
    {
    if (PointInPolygon(missile, polygon_kingdom[i], m[i]))
    {
    v[i]
    = 1;
    }
    }
    //printf("%.2lf %.2lf\n", missile.x, missile.y);
    }

    double area = 0;
    for (int i=0; i<top; i++)
    {
    if (v[i]) {area += PolygononArea(polygon_kingdom[i], m[i]);}
    }
    printf(
    "%.2lf\n", area);
    break;
    }
    for (int i=0; i<n; i++)
    {
    scanf(
    "%lf%lf", &kingdom[top][i].x, &kingdom[top][i].y);
    }
    //printf("---------\n");

    graham(kingdom[top], n, polygon_kingdom[top], m[top]);

    top
    ++;
    }
    return 0;
    }
  • 相关阅读:
    结对-贪吃蛇游戏结对编项目设计文档
    java基础语法day04
    java基础语法day03
    轻量化ViewController的几个小技巧
    __weak与__block修饰符的区别
    OC与Swift的主要区别
    copy与retain /深拷贝与浅拷贝
    如何理解MVC设计模式
    iOS常见加密方法
    关于RunLoop
  • 原文地址:https://www.cnblogs.com/nigel0913/p/2170368.html
Copyright © 2020-2023  润新知