天梯 - 神坛(计算几何、极角排序求三角形最小面积)
天梯 - 神坛(计算几何、极角排序求三角形最小面积)
在古老的迈瑞城,巍然屹立着 n 块神石。长老们商议,选取 3 块神石围成一个神坛。因为神坛的能量强度与它的面积成反比,因此神坛的面积越小越好。
特殊地,如果有两块神石坐标相同,或者三块神石共线,神坛的面积为 0.000
。
长老们发现这个问题没有那么简单,于是委托你编程解决这个难题。
输入格式:
输入在第一行给出一个正整数 n(3 ≤ n ≤ 5000)。随后 n 行,每行有两个整数,分别表示神石的横坐标、纵坐标(−109 =< 横坐标、纵坐标 < 109)。
输出格式:
在一行中输出神坛的最小面积,四舍五入保留 3 位小数。
输入样例:
输出样例:
样例解释
输出的数值等于图中红色或紫色框线的三角形的面积。
题意
N个点求最小三角形。
题解
关于极角排序:https://www.cnblogs.com/aiguona/p/7248311.html
极角排序大致用法:
关于叉积:叉积=0是指两向量平行(重合);叉积>0,则向量a在向量b的顺时针方向(粗略的理解为在a在b的下方);叉积<0,则向量a在向量b的逆时针方向(粗略的理解为在a在b的上方)
我们利用叉积按极角从小到大排序。因此可以给定平面上的一些点,把它们按照一个选定的中心点排成顺(逆)时针。
先遍历每个点,将其当做中心点,和其他点组成最多n-1个向量,然后按照极角排序的思想将这些向量按顺时针或逆时针排序,然后用叉乘法用相邻两个向量求面积,更新最小值即可。
1 #include <bits/stdc++.h> 2 const int INF=0x3f3f3f3f; 3 typedef long long LL; 4 const double eps =1e-8; 5 const int mod=1e9+7; 6 const int maxn=1e5+10; 7 using namespace std; 8 9 struct node 10 { 11 LL x,y; 12 }P[5005],C[5005];//P存点,C存向量 13 14 bool cmp(node a,node b)//向量按顺时针排序 15 { 16 return a.x*b.y-a.y*b.x > 0; 17 } 18 19 int main() 20 { 21 #ifdef DEBUG 22 freopen("sample.txt","r",stdin); 23 #endif 24 25 int n; 26 scanf("%d",&n); 27 for(int i=1;i<=n;i++) 28 scanf("%lld %lld",&P[i].x,&P[i].y); 29 LL ans=0x3f3f3f3f3f3f3f3f; 30 for(int i=1;i<=n;i++) 31 { 32 int cnt=0; 33 for(int j=1;j<=n;j++) 34 { 35 if(i!=j) 36 { 37 C[++cnt].x=P[j].x-P[i].x; 38 C[cnt].y=P[j].y-P[i].y; 39 } 40 } 41 sort(C+1,C+cnt+1,cmp); 42 for(int j=2;j<=cnt;j++) 43 ans=min(ans,abs(C[j].y*C[j-1].x - C[j].x*C[j-1].y)); 44 } 45 printf("%.3f\n",ans*1.0/2); 46 47 return 0; 48 }
-