维护一个下凸包是显然的
于是乎我们可以先按照斜率排序,斜率相同时按照截距排序。
然后我们可以维护一个单调栈,满足相邻两条直线交点坐标不降(注意,不是递增)
跑完之后输出序号就ok啦。
我才不会说我是学hzwer的呢
/**************************************************************
Problem: 1007
User: zhouyuyang
Language: C++
Result: Accepted
Time:340 ms
Memory:3440 kb
****************************************************************/
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#define N 50005
#define eps 1e-9
using namespace std;
struct orz{
double a,b;//y=ax+b
int x;//记录原来位置
};
orz a[N],st[N];
int ans[N],top,n;
inline bool cmp(orz a,orz b){
if (fabs(a.a-b.a)<eps) return a.b<b.b;
return a.a<b.a;
}
double cross(orz a,orz b){return (b.b-a.b)/(a.a-b.a);}//两直线交点横坐标
void ins(orz a){
while (top){
if (fabs(st[top].a-a.a)<eps) top--;
else if (top>1&&cross(a,st[top-1])<=cross(st[top],st[top-1])) top--;
else break;
}
st[++top]=a;
}//维护单调栈
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%lf%lf",&a[i].a,&a[i].b);
a[i].x=i;
}
sort(a+1,a+n+1,cmp);
for (int i=1;i<=n;i++) ins(a[i]);
for (int i=1;i<=top;i++) ans[st[i].x]=1;
for (int i=1;i<=n;i++)
if (ans[i]) printf("%d ",i);
return 0;
}