2018 Multi-University Training Contest 3G-HDU6325(凸包)

题意:选取多个点从第一个点到达第n个点并且要求满足条件横坐标是递增的,相邻两点之间的权值是两个点的叉积然后从第一个点到达第n个点总权值最小。

题解:因为凸包是求逆时针的时候面积包住所有点的面积最大,那么我们题目这样是顺时针,相反的就是面积最小,所以这题就是求顺时针的凸包,将中间的那些点按x从小到大,y从小到大,编号从小到大排序然后扫描法选取凸包即可,因为会有从点所以相同的点我们选取编号最小的点即可

 

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define mes(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define dec(i,a,b) for(int i = b; i >= a; i--)
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define lowbit(x) x&(-x)
typedef double db;
typedef long long int ll;
typedef pair pii;
typedef unsigned long long ull;
const ll inf = 0x3f3f3f3f;
const int mx = 2e5+5;
const int mod = 1e9+7;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
struct node{
	ll x,y;
	int id;
	bool operator<(const node &a)const{
		if(x!=a.x)	return x < a.x;
		if(y!=a.y) return y < a.y;
		return id < a.id;
	}
	bool operator!=(const node &a){
		return x!=a.x||y!=a.y;
	}
	friend node operator-(const node &a,const node &b){
		node c;
		c.x = a.x-b.x;
		c.y = a.y-b.y;
		c.id = a.id;
		return c;
	}
	ll operator*(node &a){
		return x*a.y-a.x*y;
	}
}a[mx],st[mx];
int top;
bool judge(node a,node b,node c){
	c = c-a;
	b = b-a;
	if(b*c>0)
		return true;
	else if(b*c==0&&c.id=2&&judge(st[top-1],st[top],a[i]))
				top--;
			st[++top] = a[i];
		}
		for(int i = 1; i <= top; i++)
			printf("%d%c",st[i].id,i==top?'\n':' ');
	}
	return 0;
}

 

你可能感兴趣的:(几何)