极角,指的就是以x轴正半轴为始边,逆时针转过的角,这个角的范围是[0,2π]。
极角排序就是按极角大小排序...
atan2(y,x),表示(x,y)这个点与原点连线,这条线与x轴正半轴的夹角,这里的这个极角的范围是[−π,π]的,一二象限为正,三四象限为负。所以我们从小到大排完序后,实际上是第三象限→第四象限→第一象限→第二象限。
struct node{ int x,y; double angle; inline bool operator < (const node &t) const{ return angle<t.angle; } } for (int i=1;i<=n;i++){ read(a[i].x),read(a[i].y); a[i].angle=atan2(a[i].y,a[i].x); } sort(a+1,a+n+1,cmp);
叉积
已知两点坐标,通过叉积可以求得与原点所围成的三角形的有向面积。
比如这两个点为a,b.
\(\frac{1}{2}*(a.x*b.y-a.y*b.x)\) 即为该三角形面积,那么为什么说是有向面积呢,如果这个值是正的,说明b位于a的正方向,即逆时针方向(当然,这个角度小于π),反之,如果这个面积是负的,说明b位于a的负方向,即顺时针方向。
那么我们就可以通过叉积来求极角了
struct node{ int x,y; double angle; inline int operator * (const node &t) const{ return a.x*b.y-a.y*b.x; } } inline bool cmp(node a,node b){ return a*b>0; } for (int i=1;i<=n;i++){ read(a[i].x),read(a[i].y); } sort(a+1,a+n+1,cmp);
第一种求法的常数比较优秀,但是精度有一定的损失。而叉积的求法常数较大,但是没有精度损失,可以根据情况的不同进行选择。
在古老的迈瑞城,巍然屹立着 n 块神石。长老们商议,选取 3 块神石围成一个神坛。因为神坛的能量强度与它的面积成反比,因此神坛的面积越小越好。特殊地,如果有两块神石坐标相同,或者三块神石共线,神坛的面积为 0.000。
长老们发现这个问题没有那么简单,于是委托你编程解决这个难题。
输入格式:
输入在第一行给出一个正整数 n(3 ≤ n ≤ 5000)。随后 n 行,每行有两个整数,分别表示神石的横坐标、纵坐标(−10
9
≤ 横坐标、纵坐标 <10
9
)。
输出格式:
在一行中输出神坛的最小面积,四舍五入保留 3 位小数。
输入样例:
8
3 4
2 4
1 1
4 1
0 3
3 0
1 3
4 2
输出样例:
0.500
代码
#include<iostream> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; struct node{ ll x,y; int rel; }a[5010],b[5010]; int n; bool cmp(node x,node y){ //极角排序 if( x.rel != y.rel) return x.rel < y.rel; return x.x*y.y-x.y*y.x>0; } int judge(node x) { //返回象限 if(x.x > 0 && x.y > 0) return 1; if(x.x > 0 && x.y < 0) return 2; if(x.x < 0 && x.y < 0) return 3; if(x.x < 0 && x.y > 0) return 4; } int main(){ scanf("%d",&n); for( int i=1;i<=n;i++) scanf("%lld%lld",&a[i].x,&a[i].y); double ans=-1; int cnt; for(int i=1;i<=n;i++){ cnt=1; for(int j=1;j<=n;j++){ if( i==j ) continue; b[cnt].x = a[j].x-a[i].x; b[cnt].y = a[j].y-a[i].y; b[cnt].rel = judge(b[cnt]); cnt++; } sort(b+1,b+n,cmp); for(int j=1;j<n-1;j++){ if( ans==-1||fabs(b[j+1].x*b[j].y-b[j+1].y*b[j].x)*0.5<ans ) ans=fabs(b[j+1].x*b[j].y-b[j+1].y*b[j].x)*0.5; } } printf("%.3f\n",ans); return 0; }
原文