省选专练[HNOI2008]水平可见直线

10 篇文章 0 订阅
5 篇文章 0 订阅

就是一个单纯的上凸壳

扫描法水过

#include<bits/stdc++.h>
using namespace std;
const int N=600000;
const double eps=1e-16;
struct Point{
	double x,y;
	int id;
	Point(double _x=0.0,double _y=0.0):x(_x),y(_y){}
	friend Point operator + (Point A,Point B){return Point(A.x+B.x,A.y+B.y);}
	friend Point operator - (Point A,Point B){return Point(A.x-B.x,A.y-B.y);}
	friend Point operator * (Point A,double k){return Point(A.x*k,A.y*k);}
	friend Point operator / (Point A,double k){return Point(A.x/k,A.y/k);}
	friend bool  operator < (Point A,Point B){if(fabs(A.x-B.x)<eps)return A.y<B.y;else return A.x<B.x;}
	void read(){scanf("%lf%lf",&x,&y);}
}p[N],convex_hull[N];
int n,top;
double Cross(Point A,Point B){
	return (B.y-A.y)/(A.x-B.x);
}
//void Push(int now){
//	while(Cross(p[now]-convex_hull[top-1],convex_hull[top]-convex_hull[top-1])>0)top--;
//	top++;
//	convex_hull[top]=p[now];
//}
void Push(int a)
{
	while(top)
	{
		if(fabs(convex_hull[top].x-p[a].x)<eps)top--;
		else if(top>1&&Cross(p[a],convex_hull[top-1])<=Cross(convex_hull[top],convex_hull[top-1]))
			top--;
		else break;	
	}
	convex_hull[++top]=p[a];
}
void Make_Convex_Hull(){
	convex_hull[0]=convex_hull[top=1]=p[1];
	for(int i=2;i<=n;i++){
		Push(i);
	}
}
bool cmp(Point A,Point B){
	return A.id<B.id;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		p[i].read();
		p[i].id=i;
	}
	sort(p+1,p+1+n);
	Make_Convex_Hull();
	sort(convex_hull+1,convex_hull+1+top,cmp);
	for(int i=1;i<=top;i++){
		cout<<convex_hull[i].id<<" "; 
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值