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

来源:互联网 发布:mysql 1215 编辑:程序博客网 时间:2024/05/17 16:16

C. Tavas and Pashmaks
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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
31 32 23 1
output
1 2 3 
input
31 21 12 1
output
1 3 


S/s+R/r=(S,R)*(1/s,1/r)

从上面的式子可以看出,向量(1/s,1/r)在向量(S,R)上的分量最小的就是最后赢的那个,这其实就是靠近原点那侧的闭包


#include <iostream>#include <vector>#include <algorithm>#include <cstring>#define DEBUG_OUT(a) cout<<a<<endl// #define DEBUG_OUT(a)#define print_list(a,s) for(int i=0;i<s;++i)cout<<a[i].x<<" "<<a[i].y<<endl;using namespace std;typedef long long int LL;struct Point {int x, y;};bool compare(Point a,Point b){    return (a.x < b.x) || (a.x == b.x && a.y < b.y);}//Andrew's Monotone Chainclass find_convex_hull{// 向量OA cross 向量OB。大於零表示從OA到OB為順時針旋轉。LL cross(Point& o, Point& a, Point& b){LL ox=o.x,oy=o.y;LL ax=a.x,ay=a.y;LL bx=b.x,by=b.y;    // return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);return (ox-ax)*(oy-by)*bx*ay-(oy-ay)*(ox-bx)*ax*by;}// 小於。依座標大小排序,先排 x 再排 y。public:// P為平面上的那些點。這裡設定為剛好100點。// CH為凸包上的點。這裡設定為照逆時針順序排列。void findConvexHull(Point* P,Point* CH,int size,int& m){    // 將所有點依照座標大小排序    sort(P, P+size, compare);  // print_list(P,size);    // int m = 0;  // m 為凸包頂點數目    m=0;     // 包下半部    for (int i=0; i<size; ++i) {        while (m >= 2 && cross(CH[m-2], CH[m-1], P[i]) < 0) m--;        CH[m++] = P[i];    }     // 包上半部,不用再包入方才包過的終點,但會再包一次起點    for (int i=size-2, t=m+1; i>=0; --i) {        while (m >= t && cross(CH[m-2], CH[m-1], P[i]) < 0) m--;        CH[m++] = P[i];    }}};void add_to_res(vector<int>&res,vector<int>&t){// cout<<"to add"<<endl;for(int i=0;i<t.size();++i){// cout<<"add:"<<t[i]<<endl;res.push_back(t[i]);}}bool equal(Point& a,Point& b){return (a.x==b.x)&&(a.y==b.y);}int main(){const int max_n=10010;Point candidates[max_n];int dist[max_n];vector<int> dist_count[max_n];memset(dist , 0,sizeof(dist));int n;cin>>n;do{int s,r;for(int i=0;i<n;++i){cin>>s>>r;if(dist[s]==r){dist_count[s].push_back(i+1);}else if(dist[s]<r){dist[s]=r;dist_count[s].clear();dist_count[s].push_back(i+1);}}}while(false);int nc=0;Point L,R;L.y=-1;for(int i=0;i<max_n;++i){if(dist[i]!=0){candidates[nc].x=i;candidates[nc].y=dist[i];R.x=i;R.y=dist[i];if(L.y<=dist[i]){L=R;}++nc;}}Point CH[max_n<<1];int m=0;find_convex_hull fch;fch.findConvexHull(candidates, CH,nc,m);vector<int> res;bool toadd=false;int i=0;--m;while(true){Point p=CH[i%m];// cout<<p.x<<" "<<p.y<<endl;if(toadd){add_to_res(res,dist_count[p.x]);}if(equal(p,R)){add_to_res(res,dist_count[p.x]);toadd=true;}if(equal(p,L)&&toadd){break;}++i;}sort(res.begin(),res.end());for(int i=0;i<res.size();++i){cout<<res[i]<<" ";}cout<<endl;}





0 0
原创粉丝点击