hdu6325 /// 上凸包

题目大意:

给定n 为n个点

给定n个点的坐标

两个点(xi,yi) (xj,yj)之间的花费是 xi*yj-yi*xj (可能为负数)

要求从点1经过若干个点到点n最小花费的路径 且路径要按x轴方向(即x递增)

输出路径顺序经过的点的编号

使花费最小 而花费又可能为负数 那么就尽量使得花费为负数

所以点的方向一直为顺时针的话就能使得花费最小 也就是一个上凸包

题解:https://www.cnblogs.com/mountaink/p/9591414.html

BTW 这题似乎没有考虑精度误差 加上精度误差的判断反而会WA

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define LL long long
#define mem(i,j) memset(i,j,sizeof(i))
using namespace std;
const int N=2e5+5;
const int MOD=1e9+7;
const double EPS=1e-8;

struct P {
    double x,y; int id=0;
    P(){} P(double x,double y):x(x),y(y){}
    P operator -(P p) { return P(x-p.x,y-p.y); }
    P operator +(P p) { return P(x+p.x,y+p.y); }
    double dot(P p) { return x*p.x+y*p.y; }
    double det(P p) { return x*p.y-y*p.x; }
    bool operator <(const P& p)const {
        if(x!=p.x) return x<p.x;
        if(y!=p.y) return y<p.y;
        return id<p.id;
    }
    bool operator ==(const P& p)const {
        return x==p.x && y==p.y;
    }
    void scf() { scanf("%lf%lf",&x,&y); }
}p[N], ans[N];
int n;
int andrew() {
    sort(p+1,p+1+n);
    int c=0;
    for(int i=1;i<=n;i++) {
        if(i>1 && p[i]==ans[c-1]) continue;
        while(c>1 && (p[i]-ans[c-1]).det(ans[c-2]-ans[c-1])>=0) {
            if((p[i]-ans[c-1]).det(ans[c-2]-ans[c-1])>0) c--;
            else if(ans[c-1].id>p[i].id) c--;
            else break;
        }
        ans[c++]=p[i];
    }
    return c;
}

int main()
{
    int t; scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) p[i].scf(), p[i].id=i;
        int c=andrew();
        for(int i=0;i<c-1;i++)
            printf("%d ",ans[i].id);
        printf("%d\n",ans[c-1].id);
    }

    return 0;
}

原文地址:https://www.cnblogs.com/zquzjx/p/10322451.html

时间: 2024-10-08 22:18:06

hdu6325 /// 上凸包的相关文章

2018 Multi-University Training Contest 3 1007 / hdu6325 Problem G. Interstellar Travel 凸包

Problem G. Interstellar Travel 题意: 给定平面上n个点,起点1 为(0,0),终点 n 为(Xn, 0),其它点的横坐标 0 <Xi<Xn,纵坐标 Xi >=0.每次可以飞到一个横坐标严格更大的点,代价为两个坐标的叉积.求起点到终点总代价最小的飞行路线,并输出字典序最小的路线.2≤n≤200000. Shortest judge solution: 979 bytes 题解: 显然坐标相同的点里只保留编号最小的点最优. 将起点到终点的路径补全为终点往下走到

hdu6325 Interstellar Travel 凸包变形

题目传送门 题目大意: 给出n个平面坐标,保证第一个点和第n个点y值为0,其余点的x坐标都在中间,要从 i 点走到 j 点的要求是 i 点的横坐标严格小于 j 的横坐标,并且消耗的能量是(xi * yj - xj * yi),要求消耗的能量最小(能量可以为负),并且字典序要求最小. 思路: 消耗能量的式子就是两个坐标的叉积,叉积的几何意义就是两个向量对应的平行四边形的面积,但是这个面积会有正负,如果向量 j 在向量 i 的顺时针方向,则这个面积是负的,如果我希望能量最小,那么就尽可能使向量是顺时

hdu 1348 Wall(凸包模板题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3386    Accepted Submission(s): 968 Problem Description Once upon a time there was a gre

计算几何-凸包算法 Python实现与Matlab动画演示

凸包算法是计算几何中的最经典问题之一了.给定一个点集,计算其凸包.凸包是什么就不罗嗦了 本文给出了<计算几何——算法与应用>中一书所列凸包算法的Python实现和Matlab实现,并给出了一个Matlab动画演示程序. 啊,实现谁都会实现啦╮(╯▽╰)╭,但是演示就不一定那么好做了. 算法CONVEXHULL(P)  输入:平面点集P  输出:由CH(P)的所有顶点沿顺时针方向组成的一个列表 1.   根据x-坐标,对所有点进行排序,得到序列p1, …, pn 2.   在Lupper中加入p

poj 1113 Wall(标准的凸包果题)

题目链接:http://poj.org/problem?id=1113 Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he would not listen to his Architect's proposals to build

HDU1392:Surround the Trees(凸包问题)

Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7164    Accepted Submission(s): 2738 Problem Description There are a lot of trees in an area. A peasant wants to buy a rope to

poj1228 Grandpa&#39;s Estate 凸包

Description Being the only living descendant of his grandfather, Kamran the Believer inherited all of the grandpa's belongings. The most valuable one was a piece of convex polygon shaped farm in the grandpa's birth village. The farm was originally se

计算几何 二维凸包问题 Andrew算法

凸包:把给定点包围在内部的.面积最小的凸多边形. Andrew算法是Graham算法的变种,速度更快稳定性也更好. 首先把所有点排序,按照第一关键字x第二关键字y从小到大排序,删除重复点后得到点序列P1...Pn. 1)把P1,P2放入凸包中,凸包中的点使用栈存储 2)从p3开始,当下一个点在凸包当前前进方向(即直线p1p2)左边的时候继续: 3)否则依次删除最近加入凸包的点,直到新点在左边. 如图,新点P18在当前前进方向P10P15的右边(使用叉积判断),因此需要从凸包上删除点P15和P10

bzoj-1492 货币兑换Cash (1)——平衡树维护凸包

题意: 有n天和m的初始金钱,用来购买AB两种纪念券: n天里每天都有AB的价格.每天能够进行这种操作. 1.卖出手中x%的纪念券(AB分别都卖出x%). 2.用x的金钱买入纪念券.买入AB券的比例在第i天为Rate i: 求n天过去之后所获得的最大收益. 金钱和券数均为实数: n<=100 000: 题解: 首先,尽管题中的买入和卖出都是随意数量的.可是相同的纪念券,分几天卖出得到的收 益.一定小于等于直接在一天卖出的收益: 相同.分几天买入也是不如一天花全部钱买入的: 令: f[i]为第i天