ACM小组函数模板.docx
- 文档编号:26144637
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:74
- 大小:32.34KB
ACM小组函数模板.docx
《ACM小组函数模板.docx》由会员分享,可在线阅读,更多相关《ACM小组函数模板.docx(74页珍藏版)》请在冰豆网上搜索。
ACM小组函数模板
ACM小组内部预定函数
数学问题:
1.精度计算—大数阶乘22.精度计算—乘法(大数乘小数)2
3.精度计算——乘法(大数乘大数)34.精度计算——加法4
5.精度计算——减法56.任意进制转换6
7.最大公约数、最小公倍数68.组合序列7
9.快速傅立叶变换(FFT)810.Ronberg算法计算积分10
11.行列式计算1112.求排列组合数12
字符串处理:
1.字符串替换122.字符串查找133.字符串截取14
计算几何:
1.叉乘法求任意多边形面积142.求三角形面积15
3.两矢量间角度154.两点距离(2D、3D)16
5.射向法判断点是否在多边形内部166.判断点是否在线段上17
7.判断两线段是否相交188.判断线段与直线是否相交19
9.点到线段最短距离1910.求两直线的交点20
11.判断一个封闭图形是凹集还是凸集2112.Graham扫描法寻找凸包22
数论:
1.x的二进制长度232.返回x的二进制表示中从低到高的第i位23
3.模取幂运算244.求解模线性方程24
5.求解模线性方程组(中国余数定理)256.筛法素数产生器26
7.判断一个数是否素数26
图论:
1.Prim算法求最小生成树272.Dijkstra算法求单源最短路径28
3.Bellman-ford算法求单源最短路径294.Floyd算法求每对节点间最短路径29
排序/查找:
1.快速排序302.希尔排序313.选择法排序324.二分查找32
数据结构:
1.顺序队列332.顺序栈363.链表384.链栈42
5.二叉树44
一、数学问题
1.精度计算——大数阶乘
语法:
intresult=factorial(intn);
参数:
n:
n的阶乘
返回值:
阶乘结果的位数
注意:
本程序直接输出n!
的结果,需要返回结果请保留longa[]
需要math.h
源程序:
intfactorial(intn)
{
longa[10000];
inti,j,l,c,m=0,w;
a[0]=1;
for(i=1;i<=n;i++)
{
c=0;
for(j=0;j<=m;j++)
{
a[j]=a[j]*i+c;
c=a[j]/10000;
a[j]=a[j]%10000;
}
if(c>0){m++;a[m]=c;}
}
w=m*4+log10(a[m])+1;
printf("\n%ld",a[m]);
for(i=m-1;i>=0;i--)printf("%4.4ld",a[i]);
returnw;
}
2.精度计算——乘法(大数乘小数)
语法:
mult(charc[],chart[],intm);
参数:
c[]:
被乘数,用字符串表示,位数不限
t[]:
结果,用字符串表示
m:
乘数,限定10以内
返回值:
null
注意:
需要string.h
源程序:
voidmult(charc[],chart[],intm)
{
inti,l,k,flag,add=0;
chars[100];
l=strlen(c);
for(i=0;i s[l-i-1]=c[i]-'0'; for(i=0;i { k=s[i]*m+add; if(k>=10){s[i]=k%10;add=k/10;flag=1;}else{s[i]=k;flag=0;add=0;} } if(flag){l=i+1;s[i]=add;}elsel=i; for(i=0;i t[l-1-i]=s[i]+'0'; t[l]='\0'; } 3.精度计算——乘法(大数乘大数) 语法: mult(chara[],charb[],chars[]); 参数: a[]: 被乘数,用字符串表示,位数不限 b[]: 乘数,用字符串表示,位数不限 t[]: 结果,用字符串表示 返回值: null 注意: 空间复杂度为o(n^2) 需要string.h 源程序: voidmult(chara[],charb[],chars[]) { inti,j,k=0,alen,blen,sum=0,res[65][65]={0},flag=0; charresult[65]; alen=strlen(a);blen=strlen(b); for(i=0;i for(j=0;j for(i=alen-1;i>=0;i--) { for(j=blen-1;j>=0;j--)sum=sum+res[i+blen-j-1][j]; result[k]=sum%10; k=k+1; sum=sum/10; } for(i=blen-2;i>=0;i--) { for(j=0;j<=i;j++)sum=sum+res[i-j][j]; result[k]=sum%10; k=k+1; sum=sum/10; } if(sum! =0){result[k]=sum;k=k+1;} for(i=0;i for(i=k-1;i>=0;i--)s[i]=result[k-1-i]; s[k]='\0'; while (1) { if(strlen(s)! =strlen(a)&&s[0]=='0') strcpy(s,s+1); else break; } } 4.精度计算——加法 语法: add(chara[],charb[],chars[]); 参数: a[]: 被乘数,用字符串表示,位数不限 b[]: 乘数,用字符串表示,位数不限 t[]: 结果,用字符串表示 返回值: null 注意: 空间复杂度为o(n^2) 需要string.h 源程序: voidadd(chara[],charb[],charback[]) { inti,j,k,up,x,y,z,l; char*c; if(strlen(a)>strlen(b))l=strlen(a)+2;elsel=strlen(b)+2; c=(char*)malloc(l*sizeof(char)); i=strlen(a)-1; j=strlen(b)-1; k=0;up=0; while(i>=0||j>=0) { if(i<0)x='0';elsex=a[i]; if(j<0)y='0';elsey=b[j]; z=x-'0'+y-'0'; if(up)z+=1; if(z>9){up=1;z%=10;}elseup=0; c[k++]=z+'0'; i--;j--; } if(up)c[k++]='1'; i=0; c[k]='\0'; for(k-=1;k>=0;k--) back[i++]=c[k]; back[i]='\0'; } 5.精度计算——减法 语法: sub(chars1[],chars2[],chart[]); 参数: s1[]: 被减数,用字符串表示,位数不限 s2[]: 减数,用字符串表示,位数不限 t[]: 结果,用字符串表示 返回值: null 注意: 默认s1>=s2,程序未处理负数情况 需要string.h 源程序: voidsub(chars1[],chars2[],chart[]) { inti,l2,l1,k; l2=strlen(s2);l1=strlen(s1); t[l1]='\0';l1--; for(i=l2-1;i>=0;i--,l1--) { if(s1[l1]-s2[i]>=0) t[l1]=s1[l1]-s2[i]+'0'; else { t[l1]=10+s1[l1]-s2[i]+'0'; s1[l1-1]=s1[l1-1]-1; } } k=l1; while(s1[k]<0){s1[k]+=10;s1[k-1]-=1;k--;} while(l1>=0){t[l1]=s1[l1];l1--;} loop: if(t[0]=='0') { l1=strlen(s1); for(i=0;i t[l1-1]='\0'; gotoloop; } if(strlen(t)==0){t[0]='0';t[1]='\0';} } 6.任意进制转换 语法: conversion(chars1[],chars2[],longd1,longd2); 参数: s[]: 原进制数字,用字符串表示 s2[]: 转换结果,用字符串表示 d1: 原进制数 d2: 需要转换到的进制数 返回值: null 注意: 高于9的位数用大写'A'~'Z'表示,2~16位进制通过验证 源程序: voidconversion(chars[],chars2[],longd1,longd2) { longi,j,t,num; charc; num=0; for(i=0;s[i]! ='\0';i++) { if(s[i]<='9'&&s[i]>='0')t=s[i]-'0';elset=s[i]-'A'+10; num=num*d1+t; } i=0; while (1) { t=num%d2; if(t<=9)s2[i]=t+'0';elses2[i]=t+'A'-10; num/=d2; if(num==0)break; i++; } for(j=0;j {c=s2[j];s2[j]=s[i-j];s2[i-j]=c;} s2[i+1]='\0'; } 7.最大公约数、最小公倍数 语法: resulet=hcf(inta,intb)、result=lcd(inta,intb) 参数: a: inta,求最大公约数或最小公倍数 b: intb,求最大公约数或最小公倍数 返回值: 返回最大公约数(hcf)或最小公倍数(lcd) 注意: lcd需要连同hcf使用 源程序: inthcf(inta,intb) { intr=0; while(b! =0) { r=a%b; a=b; b=r; } return(a); } lcd(intu,intv,inth) { return(u*v/h); } 8.组合序列 语法: m_of_n(intm,intn1,intm1,int*a,inthead) 参数: m: 组合数C的上参数 n1: 组合数C的下参数 m1: 组合数C的上参数,递归之用 *a: 1~n的整数序列数组 head: 头指针 返回值: null 注意: *a需要自行产生 初始调用时,m=m1、head=0 调用例子: 求C(m,n)序列: m_of_n(m,n,m,a,0); 源程序: voidm_of_n(intm,intn1,intm1,int*a,inthead) { inti,t; if(m1<0||m1>n1)return; if(m1==n1) { for(i=0;i cout<<'\n'; return; } m_of_n(m,n1-1,m1,a,head);//递归调用 t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t; m_of_n(m,n1-1,m1-1,a,head+1);//再次递归调用 t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t; } 9.快速傅立叶变换(FFT) 语法: kkfft(doublepr[],doublepi[],intn,intk,doublefr[],doublefi[],intl,intil); 参数: pr[n]: 输入的实部 pi[n]: 数入的虚部 n,k: 满足n=2^k fr[n]: 输出的实部 fi[n]: 输出的虚部 l: 逻辑开关,0FFT,1ifFT il: 逻辑开关,0输出按实部/虚部;1输出按模/幅角 返回值: null 注意: 需要math.h 源程序: voidkkfft(pr,pi,n,k,fr,fi,l,il) intn,k,l,il; doublepr[],pi[],fr[],fi[]; { intit,m,is,i,j,nv,l0; doublep,q,s,vr,vi,poddr,poddi; for(it=0;it<=n-1;it++) { m=it;is=0; for(i=0;i<=k-1;i++) {j=m/2;is=2*is+(m-2*j);m=j;} fr[it]=pr[is];fi[it]=pi[is]; } pr[0]=1.0;pi[0]=0.0; p=6.283185306/(1.0*n); pr[1]=cos(p);pi[1]=-sin(p); if(l! =0)pi[1]=-pi[1]; for(i=2;i<=n-1;i++) { p=pr[i-1]*pr[1]; q=pi[i-1]*pi[1]; s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]); pr[i]=p-q;pi[i]=s-p-q; } for(it=0;it<=n-2;it=it+2) { vr=fr[it];vi=fi[it]; fr[it]=vr+fr[it+1];fi[it]=vi+fi[it+1]; fr[it+1]=vr-fr[it+1];fi[it+1]=vi-fi[it+1]; } m=n/2;nv=2; for(l0=k-2;l0>=0;l0--) { m=m/2;nv=2*nv; for(it=0;it<=(m-1)*nv;it=it+nv) for(j=0;j<=(nv/2)-1;j++) { p=pr[m*j]*fr[it+j+nv/2]; q=pi[m*j]*fi[it+j+nv/2]; s=pr[m*j]+pi[m*j]; s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]); poddr=p-q;poddi=s-p-q; fr[it+j+nv/2]=fr[it+j]-poddr; fi[it+j+nv/2]=fi[it+j]-poddi; fr[it+j]=fr[it+j]+poddr; fi[it+j]=fi[it+j]+poddi; } } if(l! =0) for(i=0;i<=n-1;i++) { fr[i]=fr[i]/(1.0*n); fi[i]=fi[i]/(1.0*n); } if(il! =0) for(i=0;i<=n-1;i++) { pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]); if(fabs(fr[i])<0.000001*fabs(fi[i])) { if((fi[i]*fr[i])>0)pi[i]=90.0; elsepi[i]=-90.0; } else pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306; } return; } 10.Ronberg算法计算积分 语法: result=integral(doublea,doubleb); 参数: a: 积分上限 b: 积分下限 functionf: 积分函数 返回值: f在(a,b)之间的积分值 注意: functionf(x)需要自行修改,程序中用的是sina(x)/x 需要math.h 默认精度要求是1e-5 源程序: doublef(doublex) { returnsin(x)/x;//在这里插入被积函数 } doubleintegral(doublea,doubleb) { doubleh=b-a; doublet1=(1+f(b))*h/2.0; intk=1; doubler1,r2,s1,s2,c1,c2,t2; loop: doubles=0.0; doublex=a+h/2.0; while(x { s+=f(x); x+=h; } t2=(t1+h*s)/2.0; s2=t2+(t2-t1)/3.0; if(k==1) { k++;h/=2.0;t1=t2;s1=s2; gotoloop; } c2=s2+(s2-s1)/15.0; if(k==2){ c1=c2;k++;h/=2.0; t1=t2;s1=s2; gotoloop; } r2=c2+(c2-c1)/63.0; if(k==3){ r1=r2;c1=c2;k++; h/=2.0; t1=t2;s1=s2; gotoloop; } while(fabs(1-r1/r2)>1e-5){ r1=r2;c1=c2;k++; h/=2.0; t1=t2;s1=s2; gotoloop; } returnr2; } 11.行列式计算 语法: result=js(ints[][],intn) 参数: s[][]: 行列式存储数组 n: 行列式维数,递归用 返回值: 行列式值 注意: 函数中常数N为行列式维度,需自行定义 源程序: intjs(s,n) ints[][N],n; { intz,j,k,r,total=0; intb[N][N];/*b[N][N]用于存放,在矩阵s[N][N]中元素s[0]的余子式*/ if(n>2) { for(z=0;z { for(j=0;j for(k=0;k if(k>=z)b[j][k]=s[j+1][k+1];elseb[j][k]=s[j+1][k]; if(z%2==0)r=s[0][z]*js(b,n-1);/*递归调用*/ elser=(-1)*s[0][z]*js(b,n-1); total=total+r; } } elseif(n==2) total=s[0][0]*s[1][1]-s[0][1]*s[1][0]; returntotal; } 12.求排列组合数 语法: result=P(longn,longm);/result=longC(longn,longm); 参数: m: 排列组合的上系数 n: 排列组合的下系数 返回值: 排列组合数 注意: 符合数学规则: m<=n 源程序: longP(longn,longm) { longp=1; while(m! =0) {p*=n;n--;m--;} returnp; } longC(longn,longm) { longi,c=1; i=m; while(i! =0) {c*=n;n--;i--;} while(m! =0) {c/=m;m--;} returnc; } 二、字符串处理 1.字符串替换 语法: replace(charstr[],charkey[],charswap[]); 参数: str[]: 在此源字符串进行替换操作 key[]: 被替换的字符串,不能为空串 swap[]: 替换的字符串,可以为空串,为空串表示在源字符中删除key[] 返回值: null 注意: 默认str[]长度小于1000,如否,重新设定设定tmp大小 需要string.h 源程序: voidreplace(charstr[],charkey[],charswap[]) { intl1,l2,l3,i,j,flag; chartmp[1000]; l1=strlen(str); l2=strlen(key); l3=strlen(swap); for(i=0;i<=l1-l2;i++) { flag=1; for(j=0;j if(str[i+j]! =key[j]){flag=0;break;} if(flag) { strcpy(tmp,str); strcpy(&tmp[i],swap); strcpy(&tmp[i+l3],&str[i+l2]); strcpy(str,tmp); i+=l3-1; l1=strlen(str); } } } 2.字符串查找 语法: result=strfind(charstr[],charkey[]); 参数: str[]: 在此源字符串进行查找操作 key[]: 被查找的字符串,不能为空串 返回值: 如果查找成功,返回key在str中第一次出现的位置,否则返回-1 注意: 需要string.h 源程序: intstrfind(ch
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ACM 小组 函数 模板