1. 程式人生 > >hdu6325 Interstellar Travel 凸包變形

hdu6325 Interstellar Travel 凸包變形

oss ins sca 叉積 lse self index ems tac

題目傳送門

題目大意:

給出n個平面坐標,保證第一個點和第n個點y值為0,其余點的x坐標都在中間,要從 i 點走到 j 點的要求是 i 點的橫坐標嚴格小於 j 的橫坐標,並且消耗的能量是(xi * yj - xj * 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(1T10), denoting the number of test cases.
In each test case, there is an integer n(2n200000) in the first line, denoting the number of planets.
For the next n lines, each line contains 2 integers xi,yi(0xi,yi109), 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(1pin), denoting the route you chosen is p1p2...pm?1pm. 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

hdu6325 Interstellar Travel 凸包變形