L3-021 神坛 (30 分)
在古老的迈瑞城,巍然屹立着 n 块神石。长老们商议,选取 3 块神石围成一个神坛。因为神坛的能量强度与它的面积成反比,因此神坛的面积越小越好。特殊地,如果有两块神石坐标相同,或者三块神石共线,神坛的面积为 0.000
。
长老们发现这个问题没有那么简单,于是委托你编程解决这个难题。
输入格式:
输入在第一行给出一个正整数 n(3 ≤ n ≤ 5000)。随后 n 行,每行有两个整数,分别表示神石的横坐标、纵坐标(−109≤ 横坐标、纵坐标 <109)。
输出格式:
在一行中输出神坛的最小面积,四舍五入保留 3 位小数。
输入样例:
8
3 4
2 4
1 1
4 1
0 3
3 0
1 3
4 2
输出样例:
0.500
样例解释
输出的数值等于图中红色或紫色框线的三角形的面积。
极角排序,遍历每个点和其余所有点向量,找的相邻两条线段,求三角形面积
叉积 absin(),三角形面积 0.5absin()
AC代码:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 5010;
struct point{
long long x,y;
}p1[N],p2[N];
bool cmp(point point1,point point2){
return point1.x*point2.y-point2.x*point1.y>0;
}
int main(){
// freopen("1.txt","r",stdin);
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lld%lld",&p1[i].x,&p1[i].y);
}
double ans=-1;
for(int i=0;i<n;i++){
int cnt=0;
for(int j=0;j<n;j++){
if(i==j) continue;
p2[cnt].x=p1[j].x-p1[i].x;
p2[cnt].y=p1[j].y-p1[i].y;
cnt++;
}
sort(p2,p2+cnt,cmp);
//n-1条向量
for(int j=0;j<n-2;j++){
if(ans==-1||ans>p2[j].x*p2[j+1].y-p2[j+1].x*p2[j].y)
ans=p2[j].x*p2[j+1].y-p2[j+1].x*p2[j].y;
}
}
printf("%.3f",ans*0.5);
return 0;
}