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


    C. Tavas and Pashmaks
     

    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.

    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("
    ");
    104 
    105     }
    106 
    107     return 0;
    108 }
     
  • 相关阅读:
    C/C++ 编程中的内存屏障(Memory Barriers) (1)
    ubuntu 10.04 源
    内存屏障(经典)
    VMware设置桥接上网
    C/C++ 编程中的内存屏障(Memory Barriers) (2)
    寒假Day55:指针
    寒假Day54:poj2378Tree Cutting没用树形dp写的树的题dfs
    寒假Day50:CodeForces1324CFrog Jumps思维
    寒假Day50:51nod3047位移运算
    寒假Day53:Codeforces519B水题
  • 原文地址:https://www.cnblogs.com/oneshot/p/4433121.html
Copyright © 2020-2023  润新知