Tavas is a cheerleader in the new sports competition named "Pashmaks".
This competition consists of two part: swimming and then running. People will immediately start running R meters after they finished swimming exactly S meters. A winner is a such person that nobody else finishes running before him/her (there may be more than one winner).
Before the match starts, Tavas knows that there are n competitors registered for the match. Also, he knows that i-th person's swimming speed is si meters per second and his/her running speed is ri meters per second. Unfortunately, he doesn't know the values of R and S, but he knows that they are real numbers greater than 0.
As a cheerleader, Tavas wants to know who to cheer up. So, he wants to know all people that might win. We consider a competitor might win if and only if there are some values of R and S such that with these values, (s)he will be a winner.
Tavas isn't really familiar with programming, so he asked you to help him.
The first line of input contains a single integer n (1 ≤ n ≤ 2 × 105).
The next n lines contain the details of competitors. i-th line contains two integers si and ri (1 ≤ si, ri ≤ 104).
In the first and the only line of output, print a sequence of numbers of possible winners in increasing order.
3
1 3
2 2
3 1
1 2 3
3
1 2
1 1
2 1
1 3
题意:n个人比赛,游泳和赛跑,游泳距离S,赛跑R。 每个人对应两个速度(陆地和水上的), 如果存在 S , R,使得第i个人胜利,那么输出i。
题目要求 :输出所有的i。
可以把 ri si的倒数看成坐标系上的点,时间可以当做 两个向量的点积也就是投影。。。
求出凸包。 p1 为最下面的点如果有多个选取最左面的那个, p2位最左面的点如果有多个选取最下面的那个。 那么凸包上从p1到p2的点必然满足题意。注意判重
1 #include <bits/stdc++.h> 2 using namespace std; 3 const double eps = 1e-16; 4 const int inf = 0x3f3f3f3f; 5 struct Point 6 { 7 double x, y; 8 int idx; 9 Point (double x = 0, double y = 0): 10 x(x), y(y) {} 11 bool operator == (const Point &rhs)const 12 { 13 return abs(x - rhs.x) < eps && (y - rhs.y) < eps; 14 } 15 bool operator < (const Point &rhs) const 16 { 17 return x < rhs.x || (abs(x-rhs.x) < eps && y < rhs. y); 18 } 19 }; 20 typedef Point Vector; 21 Vector operator - (Point p1, Point p2) 22 { 23 return Vector (p1.x-p2.x, p1.y-p2.y); 24 } 25 double Cross(Vector p1, Vector p2) 26 { 27 return p1.x*p2.y - p2.x*p1.y; 28 } 29 Point p[200010], cvx[200010]; 30 bool ans[200010]; 31 int pos[200010]; 32 bool cmp(double x) 33 { 34 return x < 0 || abs(x) < eps; 35 } 36 int ConvexHull(int n) 37 { 38 sort (p, p+n); 39 // n = unique(p, p+n) - p; 40 int tot = 0; 41 for (int i = 0; i < n; i++) 42 { 43 if (i > 0 && p[i] == p[i-1]) 44 { 45 pos[i] = pos[i-1]; 46 continue; 47 } 48 pos[i] = i; 49 while (tot > 1&& cmp(Cross(cvx[tot-1]-cvx[tot-2], p[i]-cvx[tot-2])) == true) 50 tot--; 51 cvx[tot++] = p[i]; 52 } 53 int k = tot; 54 for (int i = n-2; i >= 0; i--) 55 { 56 while (tot > k && cmp(Cross(cvx[tot-1]-cvx[tot-2],p[i]-cvx[tot-2]) == true)) 57 tot--; 58 cvx[tot++] = p[i]; 59 } 60 if (n > 1) 61 tot--; 62 return tot; 63 } 64 bool cmp2(const Point &p1, const Point &p2) 65 { 66 return p1.y < p2.y || (abs(p1.y-p2.y) < eps && p1.x < p2.x); 67 } 68 int main(void) 69 { 70 #ifndef ONLINE_JUDGE 71 freopen("in.txt", "r", stdin); 72 #endif // ONLINE_JUDGE 73 int n; 74 while (~scanf ("%d", &n)) 75 { 76 memset(ans, false, sizeof(ans)); 77 memset(pos, 0, sizeof(pos)); 78 double minv1 = inf, minv2 = inf; 79 for (int i = 0; i < n; i++) 80 { 81 double s, r; 82 scanf ("%lf%lf", &s, &r); 83 minv1 = min(1000000/r, minv1); //减小误差 84 minv2 = min(minv2, 1000000/s); 85 p[i] = Point(1000000/s, 1000000/r); 86 p[i].idx = i; 87 } 88 int tot = ConvexHull(n); 89 for (int i = 0; i < tot; i++) 90 { 91 ans[cvx[i].idx] = true; 92 if (abs(cvx[i].y-minv1) < eps) 93 break; 94 } 95 for (int i = 0; i < n; i++) 96 { 97 if (ans[p[pos[i]].idx] == true) 98 ans[p[i].idx] = true; 99 } 100 for (int i = 0; i < n; i++) 101 if (ans[i] == true) 102 printf("%d ", i+1); 103 printf(" "); 104 105 } 106 107 return 0; 108 }