Codeforces Round #299 (Div. 1)C. Tavas and Pashmaks (凸壳)

C. Tavas and Pashmaks
 

Tavas is a cheerleader in the new sports competition named "Pashmaks".

Codeforces Round #299 (Div. 1)C. Tavas and 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.

Input

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).

Output

In the first and the only line of output, print a sequence of numbers of possible winners in increasing order.

Sample test(s)
input
3
1 3
2 2
3 1
output
1 2 3 
input
3
1 2
1 1
2 1
output
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("\n");

104 

105     }

106 

107     return 0;

108 }

 

 

你可能感兴趣的:(codeforces)