LICYHACM补充 模板.docx
- 文档编号:3804764
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:127
- 大小:58.11KB
LICYHACM补充 模板.docx
《LICYHACM补充 模板.docx》由会员分享,可在线阅读,更多相关《LICYHACM补充 模板.docx(127页珍藏版)》请在冰豆网上搜索。
LICYHACM补充模板
目录
1.13矢量运算求几何模板1
1.14结构体表示几何图形5
3.4欧拉函数7
3.7高斯消元回代法7
4.排序8
4.1快速选择算法8
4.2归并排序+逆序数的求取8
5.字符串8
5.1KMP应用8
5.2后缀数组9
5.3中缀表达式转后缀表达式10
5.4Firefighters表达式求值10
6.博弈12
6.1博弈的AB剪枝12
6.1.1取石子12
6.2博弈SG函数局势分割12
7.数据结构13
7.1TRIE13
7.2线段树14
7.3并查集15
7.4树状数组16
7.5点树16
7.6STL17
7.7离散化17
8.图论18
8.02-SAT18
8.2寻找Euler回路18
8.3拓扑排序18
8.4差分约束系统18
8.5笛卡尔树18
8.6LCA和RMQ18
8.7割和桥18
8.8最小生成树(kruskal)18
8.9最短路径18
8.10最大网络流18
8.11最小费用流18
8.12最大团问题18
8.13二分图匹配18
8.14带权的最优二分图匹配18
9.搜索算法概略18
9.1迭代深搜+IDA*18
9.2分之界限法(深搜)18
9.3A*8数码问题(pascal)18
9.4优先队列广搜18
11.7读入18
11.8函数18
1.13矢量运算求几何模板
#include
#include
#include
#include
#defineMAX_N100
usingnamespacestd;
///////////////////////////////////////////////////////////////////
//常量区
constdoubleINF=1e10;//无穷大
constdoubleEPS=1e-15;//计算精度
constintLEFT=0;//点在直线左边
constintRIGHT=1;//点在直线右边
constintONLINE=2;//点在直线上
constintCROSS=0;//两直线相交
constintCOLINE=1;//两直线共线
constintPARALLEL=2;//两直线平行
constintNOTCOPLANAR=3;//两直线不共面
constintINSIDE=1;//点在图形内部
constintOUTSIDE=2;//点在图形外部
constintBORDER=3;//点在图形边界
constintBAOHAN=1;//大圆包含小圆
constintNEIQIE=2;//内切
constintXIANJIAO=3;//相交
constintWAIQIE=4;//外切
constintXIANLI=5;//相离
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//类型定义区
structPoint{//二维点或矢量
doublex,y;
doubleangle,dis;
Point(){}
Point(doublex0,doubley0):
x(x0),y(y0){}
};
structPoint3D{//三维点或矢量
doublex,y,z;
Point3D(){}
Point3D(doublex0,doubley0,doublez0):
x(x0),y(y0),z(z0){}
};
structLine{//二维的直线或线段
Pointp1,p2;
Line(){}
Line(Pointp10,Pointp20):
p1(p10),p2(p20){}
};
structLine3D{//三维的直线或线段
Point3Dp1,p2;
Line3D(){}
Line3D(Point3Dp10,Point3Dp20):
p1(p10),p2(p20){}
};
structRect{//用长宽表示矩形的方法w,h分别表示宽度和高度
doublew,h;
Rect(){}
Rect(double_w,double_h):
w(_w),h(_h){}
};
structRect_2{//表示矩形,左下角坐标是(xl,yl),右上角坐标是(xh,yh)
doublexl,yl,xh,yh;
Rect_2(){}
Rect_2(double_xl,double_yl,double_xh,double_yh):
xl(_xl),yl(_yl),xh(_xh),yh(_yh){}
};
structCircle{//圆
Pointc;
doubler;
Circle(){}
Circle(Point_c,double_r):
c(_c),r(_r){}
};
typedefvector
typedefvector
typedefvector
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//基本函数区
inlinedoublemax(doublex,doubley)
{
returnx>y?
x:
y;
}
inlinedoublemin(doublex,doubley)
{
returnx>y?
y:
x;
}
inlineboolZERO(doublex)//x==0
{
return(fabs(x) } inlineboolZERO(Pointp)//p==0 { return(ZERO(p.x)&&ZERO(p.y)); } inlineboolZERO(Point3Dp)//p==0 { return(ZERO(p.x)&&ZERO(p.y)&&ZERO(p.z)); } inlineboolEQ(doublex,doubley)//eqaul,x==y { return(fabs(x-y) } inlineboolNEQ(doublex,doubley)//notequal,x! =y { return(fabs(x-y)>=EPS); } inlineboolLT(doublex,doubley)//lessthan,x { return(NEQ(x,y)&&(x } inlineboolGT(doublex,doubley)//greaterthan,x>y { return(NEQ(x,y)&&(x>y)); } inlineboolLEQ(doublex,doubley)//lessequal,x<=y { return(EQ(x,y)||(x } inlineboolGEQ(doublex,doubley)//greaterequal,x>=y { return(EQ(x,y)||(x>y)); } //注意! ! ! //如果是一个很小的负的浮点数 //保留有效位数输出的时候会出现-0.000这样的形式, //前面多了一个负号 //这就会导致错误! ! ! ! ! ! //因此在输出浮点数之前,一定要调用次函数进行修正! inlinedoubleFIX(doublex) { return(fabs(x) 0: x; } ////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// //二维矢量运算 booloperator==(Pointp1,Pointp2) { return(EQ(p1.x,p2.x)&&EQ(p1.y,p2.y)); } booloperator! =(Pointp1,Pointp2) { return(NEQ(p1.x,p2.x)||NEQ(p1.y,p2.y)); } booloperator<(Pointp1,Pointp2) { if(NEQ(p1.x,p2.x)){ return(p1.x }else{ return(p1.y } } Pointoperator+(Pointp1,Pointp2) { returnPoint(p1.x+p2.x,p1.y+p2.y); } Pointoperator-(Pointp1,Pointp2) { returnPoint(p1.x-p2.x,p1.y-p2.y); } doubleoperator*(Pointp1,Pointp2)//计算叉乘p1×p2 { return(p1.x*p2.y-p2.x*p1.y); } doubleoperator&(Pointp1,Pointp2){//计算点积p1·p2 return(p1.x*p2.x+p1.y*p2.y); } doubleNorm(Pointp)//计算矢量p的模 { returnsqrt(p.x*p.x+p.y*p.y); } //把矢量p旋转角度angle(弧度表示) //angle>0表示逆时针旋转 //angle<0表示顺时针旋转 PointRotate(Pointp,doubleangle) { Pointresult; result.x=p.x*cos(angle)-p.y*sin(angle); result.y=p.x*sin(angle)+p.y*cos(angle); returnresult; } ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// //三维矢量运算 booloperator==(Point3Dp1,Point3Dp2) { return(EQ(p1.x,p2.x)&&EQ(p1.y,p2.y)&&EQ(p1.z,p2.z)); } booloperator<(Point3Dp1,Point3Dp2) { if(NEQ(p1.x,p2.x)){ return(p1.x }elseif(NEQ(p1.y,p2.y)){ return(p1.y }else{ return(p1.z } } Point3Doperator+(Point3Dp1,Point3Dp2) { returnPoint3D(p1.x+p2.x,p1.y+p2.y,p1.z+p2.z); } Point3Doperator-(Point3Dp1,Point3Dp2) { returnPoint3D(p1.x-p2.x,p1.y-p2.y,p1.z-p2.z); } Point3Doperator*(Point3Dp1,Point3Dp2)//计算叉乘p1xp2 { returnPoint3D(p1.y*p2.z-p1.z*p2.y, p1.z*p2.x-p1.x*p2.z, p1.x*p2.y-p1.y*p2.x); } doubleoperator&(Point3Dp1,Point3Dp2){//计算点积p1·p2 return(p1.x*p2.x+p1.y*p2.y+p1.z*p2.z); } doubleNorm(Point3Dp)//计算矢量p的模 { returnsqrt(p.x*p.x+p.y*p.y+p.z*p.z); } ////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// //点.线段.直线问题 // doubleDistance(Pointp1,Pointp2)//2点间的距离 { returnsqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); } doubleDistance(Point3Dp1,Point3Dp2)//2点间的距离,三维 { returnsqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z)); } doubleDistance(Pointp,LineL)//求二维平面上点到直线的距离 { return(fabs((p-L.p1)*(L.p2-L.p1))/Norm(L.p2-L.p1)); } doubleDistance(Point3Dp,Line3DL)//求三维空间中点到直线的距离 { return(Norm((p-L.p1)*(L.p2-L.p1))/Norm(L.p2-L.p1)); } boolOnLine(Pointp,LineL)//判断二维平面上点p是否在直线L上 { returnZERO((p-L.p1)*(L.p2-L.p1)); } boolOnLine(Point3Dp,Line3DL)//判断三维空间中点p是否在直线L上 { returnZERO((p-L.p1)*(L.p2-L.p1)); } intRelation(Pointp,LineL)//计算点p与直线L的相对关系,返回ONLINE,LEFT,RIGHT { doubleres=(L.p2-L.p1)*(p-L.p1); if(EQ(res,0)){ returnONLINE; }elseif(res>0){ returnLEFT; }else{ returnRIGHT; } } boolSameSide(Pointp1,Pointp2,LineL)//判断点p1,p2是否在直线L的同侧 { doublem1=(p1-L.p1)*(L.p2-L.p1); doublem2=(p2-L.p1)*(L.p2-L.p1); returnGT(m1*m2,0); } boolOnLineSeg(Pointp,LineL)//判断二维平面上点p是否在线段l上 { return(ZERO((L.p1-p)*(L.p2-p))&& LEQ((p.x-L.p1.x)*(p.x-L.p2.x),0)&& LEQ((p.y-L.p1.y)*(p.y-L.p2.y),0)); } boolOnLineSeg(Point3Dp,Line3DL)//判断三维空间中点p是否在线段l上 { return(ZERO((L.p1-p)*(L.p2-p))&& EQ(Norm(p-L.p1)+Norm(p-L.p2),Norm(L.p2-L.p1))); } PointSymPoint(Pointp,LineL)//求二维平面上点p关于直线L的对称点 { Pointresult; doublea=L.p2.x-L.p1.x; doubleb=L.p2.y-L.p1.y; doublet=((p.x-L.p1.x)*a+(p.y-L.p1.y)*b)/(a*a+b*b); result.x=2*L.p1.x+2*a*t-p.x; result.y=2*L.p1.y+2*b*t-p.y; returnresult; } boolCoplanar(Points3Dpoints)//判断一个点集中的点是否全部共面 { inti; Point3Dp; if(points.size()<4)returntrue; p=(points[2]-points[0])*(points[1]-points[0]); for(i=3;i if(! ZERO(p&points[i]))returnfalse; } returntrue; } boolLineIntersect(LineL1,LineL2)//判断二维的两直线是否相交 { return(! ZERO((L1.p1-L1.p2)*(L2.p1-L2.p2)));//是否平行 } boolLineIntersect(Line3DL1,Line3DL2)//判断三维的两直线是否相交 { Point3Dp1=L1.p1-L1.p2; Point3Dp2=L2.p1-L2.p2; Point3Dp=p1*p2; if(ZERO(p))returnfalse;//是否平行 p=(L2.p1-L1.p2)*(L1.p1-L1.p2); returnZERO(p&L2.p2);//是否共面 } boolLineSegIntersect(LineL1,LineL2)//判断二维的两条线段是否相交 { return(GEQ(max(L1.p1.x,L1.p2.x),min(L2.p1.x,L2.p2.x))&& GEQ(max(L2.p1.x,L2.p2.x),min(L1.p1.x,L1.p2.x))&& GEQ(max(L1.p1.y,L1.p2.y),min(L2.p1.y,L2.p2.y))&& GEQ(max(L2.p1.y,L2.p2.y),min(L1.p1.y,L1.p2.y))&& LEQ(((L2.p1-L1.p1)*(L1.p2-L1.p1))*((L2.p2-L1.p1)*(L1.p2-L1.p1)),0)&& LEQ(((L1.p1-L2.p1)*(L2.p2-L2.p1))*((L1.p2-L2.p1)*(L2.p2-L2.p1)),0)); } boolLineSegIntersect(Line3DL1,Line3DL2)//判断三维的两条线段是否相交 { //todo returntrue; } //计算两条二维直线的交点,结果在参数P中返回 //返回值说明了两条直线的位置关系: COLINE--共线PARALLEL--平行CROSS--相交 intCalCrossPoint(LineL1,LineL2,Point&P) { doubleA1,B1,C1,A2,B2,C2; A1=L1.p2.y-L1.p1.y; B1=L1.p1.x-L1.p2.x; C1=L1.p2.x*L1.p1.y-L1.p1.x*L1.p2.y; A2=L2.p2.y-L2.p1.y; B2=L2.p1.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LICYHACM补充 模板 LICYHACM 补充