L3-021 神坛(天梯赛)

很容易想到用叉积来表示面积 但是数据范围不允许n立方的复杂度

考虑固定了一个点,怎么取另外两个点使得面积最小

发现一定是围成多边形相临的两个点

考虑用极角排序

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=5e3+5;
int n,cnt;
int pd(double x,double y){
	if(x>0&&y>0)return 1;
	if(x>0&&y<0)return 2;
	if(x<0&&y<0)return 3;
	if(x<0&&y>0)return 4;
}
struct node{
	ll xx,yy;
}A[maxn];
struct edgg{
	ll xx,yy;
	int id;
}edg[maxn];
bool cmp(edgg a,edgg b){
	if(a.id!=b.id)return a.id<b.id;
	return a.xx*b.yy<a.yy*b.xx;
}
double S(ll x1,ll y1,ll x2,ll y2){
	return fabs(x1*y2-x2*y1)*0.5;
}
int main(){
	double ans=-1;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>A[i].xx>>A[i].yy;
	for(int i=1;i<=n;i++){
		cnt=0; 
		for(int j=1;j<=n;j++){
			if(i==j)continue;
			edg[++cnt].xx=A[i].xx-A[j].xx;
			edg[cnt].yy=A[i].yy-A[j].yy;
			edg[cnt].id=pd(edg[cnt].xx,edg[cnt].yy);
		}
		sort(edg+1,edg+1+cnt,cmp);
		for(int j=1;j<cnt;j++){
			if(ans==-1||S(edg[j].xx,edg[j].yy,edg[j+1].xx,edg[j+1].yy)<ans)
			ans=S(edg[j].xx,edg[j].yy,edg[j+1].xx,edg[j+1].yy);
		}
	}
	printf("%.3f\n",ans);
     return 0;
}

posted @ 2022-03-29 21:04  wzx_believer  阅读(58)  评论(0)    收藏  举报