1. 程式人生 > 其它 >L3-021 神壇(天梯賽)

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;
}