ACM模板.docx

上传人:b****5 文档编号:5382972 上传时间:2022-12-15 格式:DOCX 页数:40 大小:30.36KB
下载 相关 举报
ACM模板.docx_第1页
第1页 / 共40页
ACM模板.docx_第2页
第2页 / 共40页
ACM模板.docx_第3页
第3页 / 共40页
ACM模板.docx_第4页
第4页 / 共40页
ACM模板.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

ACM模板.docx

《ACM模板.docx》由会员分享,可在线阅读,更多相关《ACM模板.docx(40页珍藏版)》请在冰豆网上搜索。

ACM模板.docx

ACM模板

ACM模板---liang

一.高精度计算:

2

1.高精度加法:

2

1)C++string类实现:

2

2)字符数组char实现:

3

2.高精度减法:

3

1)C++string类实现:

3

2)字符数组char实现:

3

3.高精度乘法4

1)字符数组char实现:

4

2)C++string类实现:

4

4.高精度阶乘(压缩五位)4

5.高精度小数加法5

二.计算几何:

6

1.线段相交:

6

2.点关于直线的对称点:

点:

(a,b),直线:

Ax+By+C=06

3.求凸包7

4.多边形面积7

5.皮克定理:

8

6.三角形:

9

1)点和三角形的关系9

2)三角形各种面积算法:

9

7.两圆相交面积10

三.搜索:

10

1.DFS(深度优先、回溯)11

2.BFS(广度优先)11

四.数论:

12

1.最大公约数,最小公倍数:

12

2.欧几里德扩展:

12

3.大数除法求余、快速幂取余:

12

4.同余:

13

5.筛素数13

五.图论14

1.并查集:

14

2.最小生成树:

14

1)Prim算法14

2)克鲁斯卡尔算法15

3.最短路径:

16

1)最短路径dijkstra算法16

1)Floyd算法(最短路径)20

4.最大匹配20

5.最大流21

六.数据结构23

1.RMQ23

2.树状数组24

1)一维树状数组24

2)二维树状数组25

七.各种处理函数26

1.字符串26

1)字符串分解函数strtok26

八.动态规划27

1.最长公共子序列27

2.单调递增(递减)最长子序列28

3.整数规划:

29

 

一.高精度计算:

1.高精度加法:

1)C++string类实现:

#include

voidsum(string&a,stringb)//a=a+b

{inti,j,k,c,s;

while(a.length()>b.length())b='0'+b;//a,b处理成一样长

while(b.length()>a.length())a='0'+a;

c=0;

for(i=a.length()-1;i>=0;i--)

{s=a[i]-48+b[i]-48+c;

if(s>9){s=s%10;c=1;}elsec=0;

a[i]=48+s;

}

if(c>0)a='1'+a;

}

 

2)字符数组char实现:

#include

voidadd(chara[],charb[])//a=a+b

{

inti,j,k,sum=0;

k=strlen(a)>strlen(b)?

strlen(a):

strlen(b);

a[k+1]=0;

for(i=strlen(a)-1,j=strlen(b)-1;i>=0||j>=0;i--,j--,k--)

{if(i>=0)sum+=a[i]-'0';if(j>=0)sum+=b[j]-'0';

a[k]=sum%10+'0';sum/=10;

}

if(sum)a[0]=sum+'0';

elsestrcpy(a,&a[1]);

}

2.高精度减法:

1)C++string类实现:

#include

voidf(string&a,stringb)

{

inti,j,sum=0;

for(i=a.length()-1,j=b.length()-1;i>=0||j>=0;i--,j--)

{

sum+=a[i]-'0';if(j>=0)sum-=b[j]-'0';

if(sum<0){a[i]=sum+10+'0';sum=-1;}

else{a[i]=sum+'0';sum=0;}

}

if(a[0]=='0')a=&a[1];

for(i=0;a[i]=='0'&&i

if(i==a.length())a="0";

}

2)字符数组char实现:

#include

voidjian(chara[],charb[])//a-=b

{

inti,j,sum=0;

for(i=strlen(a)-1,j=strlen(b)-1;i>=0||j>=0;i--,j--)

{

sum+=a[i]-'0';if(j>=0)sum-=b[j]-'0';

if(sum<0){a[i]=sum+10+'0';sum=-1;}

else{a[i]=sum+'0';sum=0;}

}

if(a[0]=='0')strcpy(a,&a[1]);

for(i=0;a[i]=='0';i++);

if(i==strlen(a))strcpy(a,"0");

}

3.高精度乘法

1)字符数组char实现:

#include

voidchen(chara[],charb[])//a=a*b

{inti,j,k,l,sum,c[410]={0};

l=strlen(a)+strlen(b);

for(i=strlen(b)-1;i>=0;i--)

for(j=strlen(a)-1,k=i+j+1;j>=0;j--,k--)

{sum=(b[i]-'0')*(a[j]-'0')+c[k];

c[k]=sum%10;c[k-1]+=sum/10;

}

for(i=c[0]?

0:

1,j=0;i

a[j++]=(c[i]+'0');a[j]=0;

}

2)C++string类实现:

#include

voidchenn(string&a,stringb)//a=a*b

{inti,j,k,l,sum,c[410]={0};

l=a.length()+b.length();

for(i=b.length()-1;i>=0;i--)

for(j=a.length()-1,k=i+j+1;j>=0;j--,k--)

{sum=(b[i]-'0')*(a[j]-'0')+c[k];

c[k]=sum%10;c[k-1]+=sum/10;

}

i=c[0]?

0:

1;

while(a.length()

for(j=0;i

a[j++]=(c[i]+'0');

}

4.高精度阶乘(压缩五位)

#include

#include

usingnamespacestd;

inta[10000];

intmain(void)

{

inti,n,w,up,j;

while(cin>>n)

{

for(w=a[0]=i=1;i<=n;i++)

{for(j=0,up=0;j

{

a[j]=i*a[j]+up;

up=a[j]/100000;

a[j]%=100000;

}

if(up)a[w++]=up;

}

cout<

for(i=w-2;i>=0;i--)

cout<

}

}

5.高精度小数加法

#include

#include

voidquw0(chara[])//去除尾部多余的零eg:

3.5+3.5=7.0变成7

{inti;

for(i=0;i

if(a[i]=='.')break;

if(i!

=strlen(a))

{i=strlen(a)-1;

while(a[i]=='0'){a[i]=0;;i--;}

if(a[i]=='.')a[i]=0;;

}

}

voidadd(char*a,char*b)//a=a+b

{

inti=0,j=0,la=strlen(a),lb=strlen(b),sum=0;

while((a[i]-'.')&&i

while((b[j]-'.')&&j

if(i==la){a[i]='.';la++;};

if(j==lb){b[j]='.';lb++;};

while(la-i>lb-j){b[lb]='0';lb++;}

while(lb-j>la-i){a[la]='0';la++;}

if(la

a[la+1]=0;

b[lb]=0;

for(i=la-1,j=lb-1;i>=0;i--,j--)

{if(a[i]=='.'){a[i+1]='.';continue;}

sum+=a[i]-'0';if(j>=0)sum+=b[j]-'0';

a[i+1]=sum%10+'0';sum/=10;

}

if(sum)a[0]=sum+'0';

elsestrcpy(a,&a[1]);

quw0(a);//根据题目需要是否保留尾0

}

二.计算几何:

1.线段相交:

intxj(pointx1,pointx2,pointx3,pointx4)//相交为1,不交为0

{

if(min(x1.x,x2.x)>max(x3.x,x4.x)||min(x1.y,x2.y)>max(x3.y,x4.y)

||min(x3.x,x4.x)>max(x1.x,x2.x)||min(x3.y,x4.y)>max(x1.y,x2.y)

return0;//不交:

矩形排斥实验,最小的>最大的肯定不交

inta,b,c,d;

a=(x1.x-x2.x)*(x3.y-x1.y)-(x1.y-x2.y)*(x3.x-x1.x);//跨立实验

b=(x1.x-x2.x)*(x4.y-x1.y)-(x1.y-x2.y)*(x4.x-x1.x);

c=(x3.x-x4.x)*(x1.y-x3.y)-(x3.y-x4.y)*(x1.x-x3.x);

d=(x3.x-x4.x)*(x2.y-x3.y)-(x3.y-x4.y)*(x2.x-x3.x);

returna*b<=0&&c*d<=0;

}

2.点关于直线的对称点:

点:

(a,b),直线:

Ax+By+C=0

#include

intmain()

{

intn;

floata,b,A,B,C,a1,b1;

scanf("%d\n",&n);

while(n--)

{scanf("%f%f%f%f%f",&a,&b,&A,&B,&C);

inta1=int(a-2*A*(A*a+B*b+C)/(A*A+B*B));

intb1=int(b-2*B*(A*a+B*b+C)/(A*A+B*B));

printf("%d%d\n",a1,b1);

}

}

3.求凸包

//根据题目改动数据类型,数组大小,排序方式

#include

#defineeps1e-8

structpoint

{

intx,y;

};

pointpnt[100003],res[100005];

booloperator<(pointA,pointB)//按y排也可,具体看题目要求

{returnA.x

doublemult(pointp0,pointp1,pointp2)

{return(p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);}

//数组下标从0开始,n是点的个数,选中的点在保存在res数组中,个数是top

intgraham(pointpnt[],intn,pointres[])//选中的点在保存在res数组中,个数是top

{inti,len,k=0,top=1;

sort(pnt,pnt+n);//用cmp可能超时,原因未知

if(n==0)return0;res[0]=pnt[0];

if(n==1)return1;res[1]=pnt[1];

if(n==2)return2;res[2]=pnt[2];

for(i=2;i

{while(top&&mult(pnt[i],res[top],res[top-1])<=eps)top--;

res[++top]=pnt[i];

}

len=top;res[++top]=pnt[n-2];

for(i=n-3;i>=0;i--)

{while(top!

=len&&mult(pnt[i],res[top],res[top-1])<=eps)top--;

res[++top]=pnt[i];

}

returntop;//返回凸包中点的个数

}

4.多边形面积

//点必须是顺时针给出或逆时针给出才可用此法

//使用时注意数据类型,和数据大小

structpoint{intx,y;}a[105];

intduo(pointa[],intn)//点在数组a[]中,个数是n

{inti,s=0;

for(i=1;i<=n;i++)

s+=(a[i-1].x*a[i%n].y-a[i-1].y*a[i%n].x);

if(s<0)s=-s;

returns;

//if(s%2)cout<

//elsecout<

}

5.皮克定理:

//S=a+b÷2-1

//(其中a表示多边形内部的点数,b表示多边形边界上的点数,S表示多边形的面积)

#include

structpoint

{

intx,y;

};

intgcd(intm,intn)

{

if(n==0)returnm;

returngcd(n,m%n);

}

intbian(pointa[],intn)//算出点A和点B组成的线段上的点

{ints=0,i;

for(i=1;i<=n;i++)

s+=gcd(abs(a[i-1].x-a[i%n].x),abs(a[i-1].y-a[i%n].y));

returns;

}

intduo(pointa[],intn)//求n边形的面积,注意ans未除2;

{

inti,s=0;

for(i=1;i<=n;i++)

s+=(a[i-1].x*a[i%n].y-a[i-1].y*a[i%n].x);

if(s<0)s=-s;

returns;

}

6.三角形:

1)点和三角形的关系

//注意数据类型

#include

structpoint{intx,y;};

booloperator==(pointA,pointB){returnA.x==B.x&&A.y==B.y;}

intarea(pointA,pointB,pointC)//三角形面积,未除2

{

ints=abs((B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x));

returns;

}

intpan3(pointa[],pointp)//若点在三角形内(不含边界),返回1;

{

intsa,sb,sc,s;

s=area(a[0],a[1],a[2]);

sa=area(a[0],a[1],p);

sb=area(a[0],a[2],p);

sc=area(a[1],a[2],p);

if(sa&&sb&&sc&&s==sa+sb+sc)return1;

if((!

sa||!

sb||!

sc)&&s==sa+sb+sc)

{

if(p==a[0]||p==a[1]||p==a[2])return4;//若点在三角形顶点上,返回4。

return3;//若点在三角形边界上(不含顶点),返回3;

}

return2;//若点在三角形外(不含边界),返回2;

}

2)三角形各种面积算法:

(1)已知三点坐标:

structpoint{doublex,y;};

doublearea(pointA,pointB,pointC)//三角形面积,未除2

{

doubles=abs((B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x));

returns/2;

}

(2)已知三条边和外接圆半径,公式为s=a*b*c/(4*R)

doubleGetArea(doublea,doubleb,doublec,doubleR)

{returna*b*c/4/R;}

(3)已知三条边和内接圆半径,公式为s=pr

doubleGetArea(doublea,doubleb,doublec,doubler)

{returnr*(a+b+c)/2;}

(4)已知三角形三条边,求面积

doubleGetArea(doulea,doubleb,doublec)

{

doublep=(a+b+c)/2;

returnsqrt(p*(p-a)*(p-b)*(p-c));

}

7.两圆相交面积

#include

#include

#include

usingnamespacestd;

#defineN3.14159265354

intmain()

{

doublen,a,b,c,d,r,l,i,j,t,s1,s2;

while(cin>>a>>b>>r>>c>>d>>l)

{

t=sqrt((a-c)*(a-c)+(b-d)*(b-d));

i=acos((t*t+r*r-l*l)/(2*t*r));

j=acos((t*t-r*r+l*l)/(2*t*l));

if(t<=max(l,r)-min(l,r))cout<

elseif(t>=r+l)cout<<0.000<

else

{

s1=N*r*r*2*i/(2*N)-(sin(2*i)*r*r)/2;

s2=N*l*l*2*j/(2*N)-(sin(2*j)*l*l)/2;

cout<

}

}

}

三.搜索:

1.DFS(深度优先、回溯)

//根据题目意思,更改代码,深度可能超时,注意使用记忆式优化

voiddfs(intcur)//回溯

{

if(cur==n+1)output();//选好了所有的数

else

for(inti=1;i<=n;i++)//表示cur可以选1到n

if(!

bz[i])//没有用过就做

{

a[cur]=i;

bz[i]=true;//表示i已经用了

f(cur+1);

bz[i]=false;//把i置为没有用过,供下一次使用

}

}

2.BFS(广度优先)

//适合最少步数问题

//但不适合多情况步数问题(step+1和step+2)

structpoint

{

intx,y,step;

}s,e;

queueq;

chara[200][200];

intm,n,bz[200][200],h[8][2]={-2,-1,-2,1,2,-1,2,1,-1,-2,1,-2,-1,2,1,2};

intBFS(points)

{pointt,tt;

inti,j,x,y;

while(!

q.empty())q.pop();

q.push(s);bz[s.x][s.y]=1;

while(!

q.empty())

{

t=q.front();q.pop();

for(i=0;i<8;i++)

{

x=t.x+h[i][0];y=t.y+h[i][1];

if(x==e.x&&y==e.y)returnt.step+1;//到达结束标志

if(x>=0&&x=0&&y

{

tt.x=x;tt.y=y;tt.step=t.step+1;

bz[x][y]=1;

q.push(tt);

}

}

}

}

四.数论:

1.最大公约数,最小公倍数:

intgcd(inta,intb)//公约数

{

if(b==0)returna;

returngcd(b,a%b);

}

intd=a/gcd(a,b)*b;//公倍数,注意一定要先除再乘,否则溢出

2.欧几里德扩展:

//ax+by=Gcd(a,b)解一定存在;ax+by=c时,当c%gcd(a,b)==0有解

intexgcd(inta,intb,int&x,int&y)

{

if(b==0){x=1;y=0;returna;}

intr=exgcd(b,a%b,x,y);

intt=x;

x=y;

y=t-a/b*y;

returnr;

}

3.大数除法求余、快速幂取余:

#include

usingnamespacestd;

voidxxa(chars[],longlong&a,longlongc)//a=大数s[]%c

{

inti=0;a=0;

while(s[i])

{

a=a*10+s[i++]-'0';

a%=c;

}

}

//若a在64位内可直接套用,否则先调用xxa()

展开阅读全文
相关搜索

当前位置:首页 > 表格模板 > 表格类模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1