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


  • 相关阅读:
    sync.waitGroup的wait可以多次wait,同时通知
    广播与服务(2)
    Android中的广播与服务(包含代码)
    Android的Activity的页面跳转和数据传递
    Android基础4(get、post乱码解决、Asynchttpclient的GET_POST访问网络、上传文件、多线程下载、多线程下载的Android移植、XUtils实现多线程下载)
    Android3的知识点补充
    Android基础3(数据库创建、增删改查、事务、listView)
    Android基础2(包含测试、保存数据、获取目录等)
    关于Android的基础概念
    c++与c几点比较
  • 原文地址:https://www.cnblogs.com/staginner/p/2356230.html
Copyright © 2011-2022 走看看