hdu6325 Interstellar Travel 凸包變形
阿新 • • 發佈:2018-09-05
oss ins sca 叉積 lse self index ems tac
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.
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.
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.
題目傳送門
題目大意:
給出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) returna.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
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
hdu6325 Interstellar Travel 凸包變形