加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ PKU 1873 凸包

(2010-03-25 14:03:00)
标签:

杂谈

分类: 计算几何

    暴力枚举,求凸包即可,不用特判,因为算法本身在一颗树的时候凸包长度就是0.

    枚举用递归实现,从砍1颗~砍n-1颗一次枚举,所以不用判断在最小值相同时选砍数最少的情况(因为本来就是从砍1颗开始算的)

    代码如下,思路挺清晰的。

    #include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct Node
{
    double x, y, v, l;
}v[16], p[16];
int n, ans[16], nown, ansn, stack[16];
bool vst[16];
double extra, minv;
bool cmp(Node a, Node b)
{
    if (a.y == b.y)
        return a.x < b.x;
    return a.y  < b.y;
}
double multi(Node a, Node b, Node c, Node d)
{
    b.x -= a.x;
    b.y -= a.y;
    d.x -= c.x;
    d.y -= c.y;
    return b.x * d.y - d.x * b.y;
}
bool turn_left(Node a, Node b, Node c)
{
    return multi(a, b, b, c) > 0;
}
double dist(Node a, Node b)
{
    return sqrt(1.0 *(a.x - b.x) * (a.x - b.x) (a.y - b.y) * (a.y - b.y));
}
double Judge()
{
    int top = 1;
    stack[0] = 0;
    sort(p, p nown, cmp);
    for (int i = 1; i < nown;)
    {
        if (top == 1 || turn_left(p[stack[top - 2]], p[stack[top - 1]], p[i]))
            stack[top ] = i ;
        else top--;
    }
    int t_top = top;
    for (int i = nown - 2; i >= 0;)
    {
        if (top == t_top || turn_left(p[stack[top - 2]], p[stack[top - 1]], p[i]))
            stack[top ] = i--;
        else top--;
    }
    double ret = 0.0;
    for (int i = 0; i < top - 1; i )
        ret = dist(p[stack[i]], p[stack[i 1]]);
    return ret;
}
void dg(int deep, int num, double val, double len, int from)
{
    if (deep == num)
    {
        if (val > minv)
            return;
        int temp = 0;
        for(int k = 0; k < n; k )
            if (!vst[k])
                p[temp ] = v[k];
        double dis = Judge();
        if (len >= dis)
        {
            if (val < minv)
            {
                minv = val;
                extra = len - dis;
                ansn = 0;
                for(int k = 0; k < n; k )
                    if (vst[k])
                        ans[ansn ] = k 1;
            }
        }
        return;
    }
    for(int i = from; i < n - (num - deep - 1); i )
    {
        vst[i] = 1;
        dg(deep 1, num, val v[i].v, len v[i].l, i 1);
        vst[i] = 0;
    }
}
int main()
{
    int cnt = 1;
    while(scanf("%d", &n) && n)
    {
        for(int i = 0; i < n; i )
            scanf("%lf%lf%lf%lf", &v[i].x, &v[i].y, &v[i].v, &v[i].l);
        minv = 2000000000;
        for(int i = 1; i <= n - 1; i )
        {
            nown = n - i;
            memset(vst, 0, sizeof(vst));
            dg(0, i, 0, 0, 0);
        }
        printf("Forest %d\n", cnt );
        printf("Cut these trees:");
        for(int i = 0; i < ansn; i )
            printf(" %d", ans[i]);
        putchar('\n');
        printf("Extra wood: %.2f\n\n", extra);
    }
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有