本来以为这是一道计算几何的题
可看完题解发现。。。。。。
单调栈即可
按照a为第一关键字b为第二关键字从小到大排序
再将最小的两条线入栈,然后依次处理每条线,如果其与栈顶元素的交点在上一个点的左边,则将栈顶元素出栈
为什么是对的呢,让我们来看这个图
当我们不断往栈里加直线的时候,如果加入的直线与top-1的交点在top和top-1的交点左边,这样的话top的存在是没有任何意义的
因为斜率是单调递增的,所以我们可以用单调栈来维护
#include <bits/stdc++.h>
#define eps 1e-8
using namespace std;
const int MAXN=1e6+10;
struct node{
double a,b;
int id;
}e[MAXN],stark[MAXN];
int n,top=0,vis[MAXN]={};
inline bool mycmp(node n,node m){
if(abs(n.a-m.a)<=eps) return n.b<m.b;
else return n.a<m.a;
}
inline double cross(node xx,node yy){
return (xx.b-yy.b)/(yy.a-xx.a);
}
inline void insert(node xx){
while(top){
if(abs(stark[top].a-xx.a)<=eps) top--;
else if(top>1&&cross(xx,stark[top-1])<=cross(stark[top-1],stark[top])) top--;
else break;
}
stark[++top]=xx;
}
void init(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%lf%lf",&e[i].a,&e[i].b);
e[i].id=i;
}
sort(e+1,e+n+1,mycmp);
}
void solve(){
for(int i=1;i<=n;i++) insert(e[i]);
for(int i=1;i<=top;i++){
vis[stark[i].id]=1;
}
for(int i=1;i<=n;i++){
if(vis[i]) printf("%d ",i);
}
}
int main(){
//freopen("All.in","r",stdin);
//freopen("a.out","w",stdout);
init();
solve();
return 0;
}
注意控制精度的问题