hdu6325 Interstellar Travel 凸包变形

题目传送门

题目大意:

给出n个平面坐标,保证第一个点和第n个点y值为0,其余点的x坐标都在中间,要从 i 点走到 j 点的要求是 i 点的横坐标严格小于 j 的横坐标,并且消耗的能量是(x* y- x* yi),要求消耗的能量最小(能量可以为负),并且字典序要求最小。

思路:

消耗能量的式子就是两个坐标的叉积,叉积的几何意义就是两个向量对应的平行四边形的面积,但是这个面积会有正负,如果向量 j 在向量 i 的顺时针方向,则这个面积是负的,如果我希望能量最小,那么就尽可能使向量是顺时针方向的,由此发现其实就得到了一个凸包,而且是一个上凸包。经过凸包上的点都符合能量的要求,但是由于要求字典序最小,所以如果凸包上的某一条边上有很多点,那么就需要判断一下这些点的id,如果线段中间的点的id比较小,那么这些点选上了之后,字典序肯定会变小,所以在做凸包的时候就要对凸包算法加一点点变形。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<queue>
#include<stack>
#define CLR(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
typedef long long ll;
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 200010;
struct dian {
    double x, y;
    int id;
    dian (){}
    dian(double x, double y, int id) :x(x), y(y), id(id){}
}a[maxn],ch[maxn];
bool cmp(dian &a, dian &b)
{
    if (a.x - b.x) return a.x < b.x;
    if (a.y - b.y) return a.y < b.y;
    return a.id < b.id;
}
typedef dian Vector;
Vector operator -(Vector a, Vector b) {
    return Vector ( a.x - b.x, a.y - b.y,0 );
}
bool operator == (Vector a,Vector b){
    return ((a.x==b.x) && (a.y==b.y));
}
double cross(Vector a, Vector b)
{
    return a.x*b.y - a.y*b.x;
}
int andrew(dian *p, int n, dian *ch)
{
    int m = 0;
    sort(p, p + n, cmp);
    for (int i = 0; i < n; i++)
    {
        if(i>0&&p[i]==ch[m-1])continue;
        while (m > 1 && cross(ch[m - 2] - ch[m - 1], p[i] - ch[m - 1] )<= 0)
        {
            if(cross(ch[m - 2] - ch[m - 1], p[i] - ch[m - 1] )< 0)
            m--;
            else if(ch[m-1].id>p[i].id){
                m--;
            }else break;
        }
        ch[m++] = p[i];
    }
    return m;
}
bool vis[maxn];
int main() {
    int n,T;
    cin >> T;
    while (T--)
    {
        CLR(vis, inf);
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            scanf("%lf%lf", &a[i].x, &a[i].y);
            a[i].id = i+1;
        }
        int m = andrew(a, n, ch);
        for (int i = 0; i<=m-1; i++)
        {
            printf("%d", ch[i].id);
            if (i < m-1)printf(" ");
            else printf("\n");
        }
    }

}

/*

1
7
0 0
9 0
3 6
1 2
3 6
2 4
10 0

*/

Problem G. Interstellar Travel

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 2098    Accepted Submission(s): 544

Problem Description

After trying hard for many years, Little Q has finally received an astronaut license. To celebrate the fact, he intends to buy himself a spaceship and make an interstellar travel.
Little Q knows the position of n planets in space, labeled by 1 to n. To his surprise, these planets are all coplanar. So to simplify, Little Q put these n planets on a plane coordinate system, and calculated the coordinate of each planet (xi,yi).
Little Q plans to start his journey at the 1-th planet, and end at the n-th planet. When he is at the i-th planet, he can next fly to the j-th planet only if xi<xj, which will cost his spaceship xi×yj?xj×yi units of energy. Note that this cost can be negative, it means the flight will supply his spaceship.
Please write a program to help Little Q find the best route with minimum total cost.

Input

The first line of the input contains an integer T(1≤T≤10), denoting the number of test cases.
In each test case, there is an integer n(2≤n≤200000) in the first line, denoting the number of planets.
For the next n lines, each line contains 2 integers xi,yi(0≤xi,yi≤109), denoting the coordinate of the i-th planet. Note that different planets may have the same coordinate because they are too close to each other. It is guaranteed that y1=yn=0,0=x1<x2,x3,...,xn?1<xn.

Output

For each test case, print a single line containing several distinct integers p1,p2,...,pm(1≤pi≤n), denoting the route you chosen is p1→p2→...→pm?1→pm. Obviously p1 should be 1 and pm should be n. You should choose the route with minimum total cost. If there are multiple best routes, please choose the one with the smallest lexicographically.
A sequence of integers a is lexicographically smaller than a sequence of b if there exists such index j that ai=bi for all i<j, but aj<bj.

Sample Input

1
3
0 0
3 0
4 0

Sample Output

1 2 3

Source

2018 Multi-University Training Contest 3

原文地址:https://www.cnblogs.com/mountaink/p/9591414.html

时间: 2024-10-08 22:17:54

hdu6325 Interstellar Travel 凸包变形的相关文章

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 题解: 显然坐标相同的点里只保留编号最小的点最优. 将起点到终点的路径补全为终点往下走到

HUNNU 11568 Interstellar Travel(DP+优先队列)

Interstellar Travel Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 2, Accepted users: 1 Problem 11568 : No special judgement Problem description   In A.D. 3014, scientists find that wormhole can be used for in

【单调栈】hdu6325 Problem G. Interstellar Travel

从后往前更新,维护一个递减单调栈(队列) 最近很多题都是单调栈... #define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<algorithm> #include<queue> #include<iostream> //#include<deque> using namespace std; const int maxn = 1e7 + 5; int n, m, k, P, Q, R,

2018 HDU多校第三场赛后补题

2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube 题意: 在画布上画一个三维立方体. 题解: 模拟即可. 代码: #include <bits/stdc++.h> using namespace std; int a, b, c, R, C; char g[505][505]; int main () { int T; cin >>

poj分类解题报告索引

图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Journey poj1724 - ROADS(邻接表+DFS) BFS poj3278 - Catch That Cow(空间BFS) poj2251 - Dungeon Master(空间BFS) poj3414 - Pots poj1915 - Knight Moves poj3126 - Prim

2018 Multi-University Training Contest 3 - HDU Contest

题解: solution Code: A. Ascending Rating #include<cstdio> const int N=10000010; int T,n,m,k,P,Q,R,MOD,i,a[N],q[N],h,t;long long A,B; int main(){ scanf("%d",&T); while(T--){ scanf("%d%d%d%d%d%d%d",&n,&m,&k,&P,&am

2018 Multi-University Training Contest 3

2018 Multi-University Training Contest 2 题解 A - Problem A. Ascending Rating 题目描述:给定一个序列,分别求出所有长度为\(m\)的区间的\(maxrating, count\),对于每个长度为\(m\)的区间,一开始\(maxrating=-1, count=0\),然后从左往右扫,扫到一个大于\(maxrating\)的值时,\(count+1, maxrating=\)那个数. solution 从左往右做,用单调队

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 这题似乎没有考虑精度误差

poj2187 求平面最远点对,garham_scan算法求凸包

poj2187 求平面最远点对,garham_scan算法求凸包 Beauty Contest Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 29666   Accepted: 9180 Description Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the title 'M