基础部分
#include <bits/stdc++.h> using namespace std; #define type double #define Vector Point #define eps 1e-8 const double PI = 3.14159265358979323; type Deg2Red(type deg){ return (deg*PI/180.0); } type Rad2Deg(type rad){ return rad*180.0/PI; } inline type Abs(type x){ if(x<0)return -x; return x; } //二维点/二维向量 struct Point{ type x,y; Point(){ } Point(type x,type y):x(x),y(y){ } Point operator-(Point other){ return Point(x-other.x,y-other.y); } }; //向量点积 type Dot(Vector a,Vector b){ return a.x*b.x + a.y*b.y; } //向量叉积 type Cross(Vector a,Vector b){ return a.x*b.y - a.y*b.x; } //向量长度 double Length(Vector a){ return sqrt(a.x*a.x+a.y*a.y+0.0); } //两向量夹角 type Angle(Vector a,Vector b){ return acos(Dot(a,b) / (Length(a)*Length(b))+0.0); }
多边形
//多边形面积(点必须按顺时针或逆时针顺序给出) type Area(Point* pts,int sz){ type re=0; for(int i=0;i<sz;i++){ re+=Cross(pts[(i+1)%sz],pts[i]); } re/=2.0; if(re<0)re=-re; return re; }
平面最近点对(分治nlogn)。其实写得不优雅,要改掉。
//最近点对 type Nearest(Point* pts,int l,int r){ if(r-l==2){ return Length(pts[l+1]-pts[l]); } if(r-l==3){ double re=min(Length(pts[l+1]-pts[l]),Length(pts[l+2]-pts[l])); re=min(re,Length(pts[l+2]-pts[l+1])); return re; } int mid = (l+r)>>1; type Minl=Nearest(pts,l,mid); type Minr=Nearest(pts,mid,r); type re = min(Minl,Minr); int cnt=0; int pos; //tmp暂存分割线附近的点 pos=mid-1; while(1){ if(pos<l)break; if(pts[pos].x>pts[mid].x-re){ tmp[cnt++]=pts[pos]; pos--; }else{ break; } } pos=mid; while(1){ if(pos>=r)break; if(pts[pos].x<pts[mid].x+re){ tmp[cnt++]=pts[pos]; pos++; }else{ break; } } //感觉有点耍流氓,能不能不排序 sort(tmp,tmp+cnt,byy); //通过y排序 for(int i=0;i<cnt;i++){ for(int j=i+1;j<cnt;j++){ if(tmp[j].y-tmp[i].y>re)break; re=min(re,Length(tmp[j]-tmp[i])); } } return re; }