返回上一章 Premier Bob的算法模板库(I)
Geometry_Calculate_Basic .hpp (计算几何基础运算)
#include<cmath>
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
namespace Geometry_Calculate_Basic
{
const double PI=acos(-1.0);
struct Point{double x,y;Point(double X=0,double Y=0){x=X;y=Y;}};
typedef Point Vector;
Vector operator+(Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator-(Point A,Point B){return Point(A.x-B.x,A.y-B.y);}
Vector operator*(Vector A,double p){return Vector(A.x*p,A.y*p);}
Vector operator/(Vector A,double p){return Vector(A.x/p,A.y/p);}
bool operator<(const Point& a, const Point& b){return a.x<b.x || (a.x==b.x && a.y<b.y);}
const double eps=1e-10;
int dcmp(double x){if(fabs(x)<eps)return 0;else return x<0 ? -1 : 1;}
bool operator==(const Point& a,const Point& b){return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;}
double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y;}
double Length(Vector A){return sqrt(Dot(A,A));}
double Angle(Vector A,Vector B){return acos(Dot(A,B)/Length(A)/Length(B));}
double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}
double Area2(Point A,Point B,Point C){return Cross(B-A,C-A);}
typedef double ArcAngle;
Vector Rotate(Vector A,ArcAngle rad){return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}
Vector Normal(Vector A){double L=Length(A);return Vector(-A.y/L,A.x/L);}
Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)
{
Vector u=P-Q;
double t=Cross(w,u)/Cross(v,w);
return P+v*t;
}
double DistanceToLine(Point P,Point A,Point B)
{
Vector v1=B-A,v2=P-A;
return fabs(Cross(v1,v2))/Length(v1);
}
double DistanceToSegment(Point P,Point A,Point B)
{
if(A==B)
return Length(P-A);
Vector v1=B-A,v2=P-A,v3=P-B;
if(dcmp(Dot(v1,v2))<0)return Length(v2);
else if(dcmp(Dot(v1,v3))>0)
return Length(v3);
else return fabs(Cross(v1,v2))/Length(v1);
}
Point GetLineProjection(Point P,Point A,Point B)
{
Vector v=B-A;
return A+v*(Dot(v,P-A)/Dot(v,v));
}
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)
{
double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),
c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
double PolygonArea(Point* p,int n)
{
double area=0;
for(int i=1;i<n-1;i++)
area+=Cross(p[i]-p[0],p[i+1]-p[0]);
return area/2;
}
}
但愿这个不是使用样例:
#include"Geometry_Calculate_Basic.hpp"
int main()
{
int T;cin>>T;
for(int i=1;i<=T;i++)
{
Geometry_Calculate_Basic::Point A,B,C;
cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y;
Geometry_Calculate_Basic::ArcAngle c_a=Geometry_Calculate_Basic::Angle(A-B,C-B);
Geometry_Calculate_Basic::ArcAngle a_b=Geometry_Calculate_Basic::Angle(B-C,A-C);
Geometry_Calculate_Basic::ArcAngle b_c=Geometry_Calculate_Basic::Angle(C-A,A-B);
Geometry_Calculate_Basic::Vector a1,a2,b1,b2,c1,c2;
a1=Geometry_Calculate_Basic::Rotate(C-A,b_c/3*2);
a2=Geometry_Calculate_Basic::Rotate(C-A,b_c/3);
b1=Geometry_Calculate_Basic::Rotate(A-B,c_a/3*2);
b2=Geometry_Calculate_Basic::Rotate(A-B,c_a/3);
c1=Geometry_Calculate_Basic::Rotate(B-C,a_b/3*2);
c2=Geometry_Calculate_Basic::Rotate(B-C,a_b/3);
Geometry_Calculate_Basic::Point D,E,F;
D=Geometry_Calculate_Basic::GetLineIntersection(B,b1,C,c2);
E=Geometry_Calculate_Basic::GetLineIntersection(A,a1,B,b2);
F=Geometry_Calculate_Basic::GetLineIntersection(C,c1,A,a2);
cout<<D.x<<" "<<D.y<<" "<<E.x<<" "<<E.y<<" "<<F.x<<" "<<F.y<<endl;
}
return 0;
}
所以说应该写成这样:
#include"Geometry_Calculate_Basic.hpp"
using namespace Geometry_Calculate_Basic;
//using namespace!
int main()
{
int T;cin>>T;
for(int i=1;i<=T;i++)
{
Point A,B,C;
cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y;
ArcAngle c_a=Angle(A-B,C-B);
ArcAngle a_b=Angle(B-C,A-C);
ArcAngle b_c=Angle(C-A,A-B);
Vector a1,a2,b1,b2,c1,c2;
a1=Rotate(C-A,b_c/3*2);
a2=Rotate(C-A,b_c/3);
b1=Rotate(A-B,c_a/3*2);
b2=Rotate(A-B,c_a/3);
c1=Rotate(B-C,a_b/3*2);
c2=Rotate(B-C,a_b/3);
Point D,E,F;
D=GetLineIntersection(B,b1,C,c2);
E=GetLineIntersection(A,a1,B,b2);
F=GetLineIntersection(C,c1,A,a2);
cout<<D.x<<" "<<D.y<<" "<<E.x<<" "<<E.y<<" "<<F.x<<" "<<F.y<<endl;
}
return 0;
}
NlogN_LIS .hpp (nlogn时间复杂度求解LIS长度)
#include<algorithm>
using namespace std;
namespace NlogN_LIS
{
const int INF=2147483647;
const int maxn=1048576;
int g[maxn],d[maxn];
int LIS(int* Array,int n)
{
for(int i=1;i<=n;i++)
g[i]=INF;
int ans=0;
for(int i=1;i<=n;i++)
{
int k=lower_bound(g+1,g+n+1,Array[i])-g;
d[i]=k;
g[k]=Array[i];
ans=max(ans,d[i]);
}
return ans;
}
}
UnionFindSet .hpp (并查集模板)
//made by GGN -from NECY
#pragma once
#include<cstdio>
#include<cstdlib>
namespace UnionFindSet
{
const int UFS_Size=1048576;
//you can use this to change the size of UFS
class UFS
{
int Father[UFS_Size];
bool NeedInit;
int UseSize;
public:
UFS(){NeedInit=1;}
void Init(int NodeCount)
{
NeedInit=0;
for(int i=1;i<=NodeCount;i++)
Father[i]=i;
UseSize=NodeCount;
}
int Find(int NodeNum)
{
if(NeedInit)
{
printf("Error \"UnionFindSet\":Find you have to init before use!\n");
system("pause>nul");
return -1;
}
if(NodeNum<=0 || NodeNum>UseSize)
{
printf("Error \"UnionFindSet\":Find NodeNum=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeNum,UseSize);
system("pause>nul");
return -1;
}
if(NodeNum!=Father[NodeNum])
Father[NodeNum]=Find(Father[NodeNum]);
return Father[NodeNum];
}
int Union(int NodeX,int NodeY)
{
if(NeedInit)
{
printf("Error \"UnionFindSet\":Union you have to init before use!\n");
system("pause>nul");
return -1;
}
if(NodeX<=0 || NodeX>UseSize)
{
printf("Error \"UnionFindSet\":Union NodeX=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeX,UseSize);
system("pause>nul");
return -1;
}
if(NodeY<=0 || NodeY>UseSize)
{
printf("Error \"UnionFindSet\":Union NodeY=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeY,UseSize);
system("pause>nul");
return -1;
}
Father[Find(NodeY)]=Find(NodeX);
}
int Judge(int NodeX,int NodeY)
{
if(NeedInit)
{
printf("Error \"UnionFindSet\":Judge you have to init before use!\n");
system("pause>nul");
return -1;
}
if(NodeX<=0 || NodeX>UseSize)
{
printf("Error \"UnionFindSet\":Judge NodeX=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeX,UseSize);
system("pause>nul");
return -1;
}
if(NodeY<=0 || NodeY>UseSize)
{
printf("Error \"UnionFindSet\":Judge NodeY=%d (<=0 or >UseSize=%d) is not allowed!\n",NodeY,UseSize);
system("pause>nul");
return -1;
}
return Find(NodeX)==Find(NodeY);
}
int Ancestor(int Node)
{
if(NeedInit)
{
printf("Error \"UnionFindSet\":Ancestor you have to init before use!\n");
system("pause>nul");
return -1;
}
if(Node<=0 || Node>UseSize)
{
printf("Error \"UnionFindSet\":Ancestor Node=%d (<=0 or >UseSize=%d) is not allowed!\n",Node,UseSize);
system("pause>nul");
return -1;
}
return Father[Node];
}
};
}
TernarySearch .hpp (三分法求单峰函数最小值)
//made by GGN -from NEYC
#pragma once
#include<cstdio>
#include<cstdlib>
#include<cmath>
namespace TernarySearch
{
double TSmin(double L,double R,double (*function)(double x),double eps=1e-7)
{
//make a ternary search for min value and return x
if(R==L)
return L;
if(R<L)
{
printf("Error \"Ternary Search\":TSmin R=%d (<L=%d) is not allowed!\n",R,L);
system("pause>nul");
return L;
}
if(function==NULL)
{
printf("Error \"Ternary Search\":TSmin f=[NULL] is not allowed!\n");
system("pause>nul");
return L;
}
while(fabs(L-R)>eps)
{
double m1=L+(R-L)/3;
double m2=R-(R-L)/3;
if(function(m1)<function(m2))
R=m2;
else
L=m1;
}
return L;
}
double TSmax(double L,double R,double (*function)(double x),double eps=1e-7)
{
//make a ternary search for max value and return x
if(R==L)
return L;
if(R<L)
{
printf("Error \"Ternary Search\":TSmin R=%d (<L=%d) is not allowed!\n",R,L);
system("pause>nul");
return L;
}
if(function==NULL)
{
printf("Error \"Ternary Search\":TSmin f=[NULL] is not allowed!\n");
system("pause>nul");
return L;
}
while(fabs(L-R)>eps)
{
double m1=L+(R-L)/3;
double m2=R-(R-L)/3;
if(function(m1)>function(m2))
R=m2;
else
L=m1;
}
return L;
}
}
Treap的基本板子
后记
算法模板库仍在扩充中…