基础部分
#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;
}