zoukankan      html  css  js  c++  java
  • POJ 1113 Wall

    POJ_1113

        我们可以先将问题做一个转化:先求出城堡各点的凸包,然后求距凸包的距离为L的闭合图形的周长。

        至于为什么先转化成凸包,我们不妨用反证法,如果围墙向凸包内部的方向延伸的话必然还要延伸出来,这样就会更费料。

        围墙的形状不难想象,一部分是和边平行且等于各边的边长的,还有一部分就是墙角位置的弧形,而且这个弧形的圆心角正是两条边的方向向量的夹角。

        在计算周长的时候,一部分就是凸包的周长,另一部分就是这些弧的长度之和。我们当然可以求出每个角上的弧,然后累加到一起,但这样会涉及很多的三角函数和开方函数的运算,就会有更多精度上的损失,其实细想一下会发现把这些弧拼起来就是一个完整的圆,因此算完凸包的周长之后再加上一个半径为L的圆的周长即可。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<math.h>
    #define MAXD 1010
    struct point
    {
    int x, y;
    }p[MAXD], res[MAXD];
    int N, L, P;
    int cmp(const void *_p, const void *_q)
    {
    point *p = (point *)_p, *q = (point *)_q;
    if(p->y == q->y)
    return p->x - q->x;
    return p->y - q->y;
    }
    int det(int x1, int y1, int x2, int y2)
    {
    return x1 * y2 - x2 * y1;
    }
    void init()
    {
    int i, j, k;
    for(i = 0; i < N; i ++)
    scanf("%d%d", &p[i].x, &p[i].y);
    qsort(p, N, sizeof(p[0]), cmp);
    }
    int del(int top, int i)
    {
    if(det(res[top].x - res[top - 1].x, res[top].y - res[top - 1].y, p[i].x - res[top].x, p[i].y - res[top].y) < 0)
    return 1;
    return 0;
    }
    int graham()
    {
    int i, j, k, top = 1, mint;
    res[0] = p[0], res[1] = p[1];
    for(i = 2; i < N; i ++)
    {
    while(top && del(top, i))
    -- top;
    res[++ top] = p[i];
    }
    mint = top;
    res[++ top] = p[N - 2];
    for(i = N - 3; i >= 0; i --)
    {
    while(top != mint && del(top, i))
    -- top;
    res[++ top] = p[i];
    }
    return top;
    }
    double sqr(double x)
    {
    return x * x;
    }
    double calculate()
    {
    int i, j, k;
    double ans = 0;
    res[P + 1] = res[1];
    for(i = 0; i < P; i ++)
    ans += sqrt(sqr(res[i].x - res[i + 1].x) + sqr(res[i].y - res[i + 1].y));
    return ans + 2 * acos(-1.0) * L;
    }
    void solve()
    {
    int i, j, k;
    double ans;
    P = graham();
    ans = calculate();
    printf("%.0lf\n", ans);
    }
    int main()
    {
    while(scanf("%d%d", &N, &L) == 2)
    {
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    微人事项目-mybatis-持久层
    通过外键连接多个表
    springioc
    Redis 消息中间件 ServiceStack.Redis 轻量级
    深度数据对接 链接服务器 数据传输
    sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取
    sqlserver 索引优化 CPU占用过高 执行分析 服务器检查
    sql server 远程备份 bak 删除
    冒泡排序
    多线程 异步 beginInvoke EndInvoke 使用
  • 原文地址:https://www.cnblogs.com/staginner/p/2356230.html
Copyright © 2011-2022 走看看