ACM程序算法模板.docx
- 文档编号:7922466
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:67
- 大小:35.91KB
ACM程序算法模板.docx
《ACM程序算法模板.docx》由会员分享,可在线阅读,更多相关《ACM程序算法模板.docx(67页珍藏版)》请在冰豆网上搜索。
ACM程序算法模板
ACM程序算法模板
目录
一、组合数学1
1.1、重复性全排列算法1
1.2、C(m,n)1
1.3、无重复全组合2
1.4、大数相加3
二、数论5
2.1、最大公约数5
2.2、乘方取余5
2.3、进制转换5
2.4、素数表6
2.5、素数表精简7
2.6、N阶乘最后非0位7
2.7、约瑟夫环(不带路径)8
2.8、约瑟夫环(带路径)8
2.9、质因数分解9
2.10、判断是否为质数9
2.11、欧拉函数10
三、数据结构11
3.1、最小代价生成树—普利姆算法11
四、动态规划12
4.1、LIS最长不下降序列的算法12
4.2、交通最短路径算法14
4.3、数塔最大值算法15
4.4、最小代价字母树15
4.5、最长公共字串LCS16
4.6、可中断最长字串17
4.7、从数组中取定值18
4.8、最近点对19
4.9、24点21
4.10、01背包极大界定原始算法23
4.11、01背包极大界定空间优化26
4.12、01背包恰好装满附带组成27
4.13、01背包恰好装满空间优化30
4.14、完全背包恰好装满买咖啡题31
4.15、完全背包极大界定原始算法33
4.16、背包扩展等价匹配种数统计34
五、串35
5.1、KMP算法35
六、高精度算法36
6.1通用函数36
6.2、高精度加法37
6.3、高精度减法38
6.4、高精度乘法--高精度乘以低精度40
6.5、高精度乘法--高精度乘以高精度41
6.6、整型常量的阶乘41
6.7、整型常量的阶乘和42
6.8、高精度的乘方,幂数为整型常量42
6.9、高精度除法--高精度除以低精度,只产生余数43
6.10、高精度除法--高精度除以高精度,只产生余数44
七、排序搜索45
7.1、插入排序45
7.2、堆排序46
7.3、合并排序(分治)47
7.4、计数排序48
7.5、冒泡排序49
7.6、快速排序49
7.7、二分搜索50
八、技巧50
8.1、输入技巧50
8.2、递归51
8.3、位运算51
8.4、字典序51
8.5、省略末尾零51
一、组合数学
1.1、重复性全排列算法
#include
#include
usingnamespacestd;
intmain()
{
chars[101];
while(gets(s))
{
intn=strlen(s);
sort(s,s+n);
puts(s);
while(next_permutation(s,s+n))
puts(s);
}
return0;
}
1.2、C(m,n)
intcombination(intm,intn)//m为下标,n为上标
{
if(m<0||n<0||m n=n<(m-n)? n: m-n; if(n==0)return1; intresult=m; for(inti=2,j=result-1;i<=n;i++,j--) { result=result*j/i; } returnresult; } 1.3、无重复全组合 #include #defineMAX_N10 intn,m;//输入n个数,其中本质不同的有m个 intrcd[MAX_N];//记录每个位置填的数 intused[MAX_N];//标记m个数可以使用的次数 intnum[MAX_N];//存放输入中本质不同的m个数 voidunrepeat_combination(intl,intp) { inti; for(i=0;i { printf("%d",rcd[i]); if(i printf(""); } printf("\n"); for(i=p;i if(used[i]>0)//若还可以用,则 { used[i]--;//可用次数减1 rcd[l]=num[i];//在l位置放上该数 unrepeat_combination(l+1,i);//填下一个位置 used[i]++;//可用次数恢复 } } intread_data() { inti,j,val; if(scanf("%d",&n)==EOF) return0; m=0; for(i=0;i { scanf("%d",&val); for(j=0;j if(num[j]==val) { used[j]++; break; } if(j==m) { num[m]=val; used[m]=1; m++; } } return1; } intmain() { while(read_data()) unrepeat_combination(0,0); return0; } 1.4、大数相加 #include #include #definemax1000 intnum[max]; charcharA[max]; charcharB[max]; charcharC[max]; voidnumsum(charcharA[],charcharB[],intnum[])//两个要相加的数和最后的结果保存的数组,并且结果存放在C中 { memset(num,0,sizeof(num)); intlengthA=strlen(charA); intlengthB=strlen(charB); intlengthC=lengthA>lengthB? lengthA: lengthB; inti,j; intk=lengthC-1; i=lengthA-1; j=lengthB-1; while(i>=0&&j>=0) { num[k]=charA[i]+charB[j]-96; k--; j--; i--; } while(i>=0) { num[k]=charA[i]-48; k--; i--; } while(j>=0) { num[k]=charB[j]-48; k--; j--; } for(i=lengthC-1;i>0;i--) { num[i-1]=num[i-1]+num[i]/10; num[i]=num[i]%10; } for(i=1;i<=lengthC;i++) { charC[i]=num[i-1]+48; } charC[0]=(charC[1]-48)/10+48; charC[1]=(charC[1]-48)%10+48; if(charC[0]! ='0') printf("%c",charC[0]); for(i=1;i<=lengthC;i++) printf("%c",charC[i]); printf("\n"); } intmain() { while(scanf("%s%s",charA,charB)! =EOF) { numsum(charA,charB,num); } return0; } 二、数论 2.1、最大公约数 intgcd(intn,intm)//两个数字为参数,输出最大公约数 { if(m==0) returnn; returngcd(m,n%m); } 2.2、乘方取余 longlongexp_mod(longlonga,longlongn,longlongk)//a^n%k,返回余数 { longlongt; if(n==0)return1; if(n==1)returna%k; a%=k; t=exp_mod(a,n>>1,k); t=(t*t)%k; if(n%2==0) returnt; return(t*a)%k; } 2.3、进制转换 //10? ? 其他 inttrans(intn,intd,chars[])//数值n,转换成d(2-16)进制表示的字符串s { staticchardigits[]="0123456789ABCDEF"; charbuf[20]; intj,i=19; if(d<2||d>16) { s[0]='\0'; return0; } buf[i]='\0'; do { buf[--i]=digits[n%d]; n/=d; }while(n); for(j=0;(s[j]=buf[i])! ='\0';i++,j++); returnj; } //其他? ? 10 intn2ten(char*x,intn)//其它进制转化成十进制 { char*a; inti,j,s=0,m=1; for(i=0;x[i];i++); a=(char*)malloc((i+1)*sizeof(char)); a[i]='\0'; for(j=0,i--;i>=0;i--,j++) a[j]=x[i]; for(j=0;a[j];j++) 29{ s+=(int)(a[j]-'0')*m; m*=n; } returns; } 2.4、素数表 boolprimes[100000001]; voidmakeprimes()//素数表的产生,false是素数,这里0,1,2,3默认是。 可自己改动 { memset(primes,0,sizeof(primes)); inti,j; for(j=4;j<1001;j+=2) primes[j]=true; for(i=3;i<1001;i+=2)if(primes[i]==false) { j=i*i; if(j break; for(;j<1001;j+=2*i) primes[j]=true; } } 2.5、素数表精简 boolprimes2[10001]; voidmakeprimes2()//true则是说明是素数 { memset(primes2,1,sizeof(primes2)); primes2[0]=primes2[1]=false; inti,j; for(i=2;i<=10001;i++) { for(j=i+i;j<=10001;j+=i) { if(primes2[j]) primes2[j]=false; } } } 2.6、N阶乘最后非0位 #defineMAXN1000 intlastdigit(char*buf) { constintmod[20]={1,1,2,6,4,2,2,4,2,8,4,4,8,4,6,8,8,6,8,2}; intlen=strlen(buf),a[MAXN],i,c,ret=1; if(len==1) returnmod[buf[0]-'0']; for(i=0;i a[i]=buf[len-1-i]-'0'; for(;len;len-=! a[len-1]){ ret=ret*mod[a[1]%2*10+a[0]]%5; for(c=0,i=len-1;i>=0;i--) c=c*10+a[i],a[i]=c/5,c%=5; } returnret+ret%2*5; } 2.7、约瑟夫环(不带路径) intYueSeFu(intn,intm)/*输入几个人和每次退出的第几个,返回最后胜利者的编号*/ { ints=0; inti; for(i=2;i<=n;i++) s=(s+m)%i; returns+1; } 2.8、约瑟夫环(带路径) #include #defineMAX10000 inta[MAX]; intm,n,x;/*n为总人数,从第x个人开始从1到m报数。 */ intmain() { inti,j; scanf("%d%d%d",&n,&x,&m); for(i=1;i<=n;i++) a[i]=i; for(;n>0;n--) { x=(x+m+n-1)%n; if(x==0)x=n; printf("%d",a[x]); for(j=x;j } return0; } 2.9、质因数分解 voidsolve(intn) { intkey=0,i; if(n<0) { key=1; n=n*-1; } for(i=2;i<=n/2;i++) { if(n%i==0) { if(key==1) { printf("-"); key=0; } printf("%d",i); n=n/i; i--; } } if(n>1) printf("%d\n",n); } 2.10、判断是否为质数 boolis_prime(intn) { if(n==1) returntrue; intk=sqrt((double)n); inti; for(i=2;i<=k;++i) if(n%i==0)returnfalse; returntrue; } 2.11、欧拉函数 #include #include usingnamespacestd; #include boolis_prime(intn) { if(n==1) returntrue; intk=sqrt((double)n); inti; for(i=2;i<=k;++i) if(n%i==0)returnfalse; returntrue; } intmain() { intn; while(cin>>n&&n) { if(is_prime(n)) cout< else { doubleans=n; intd=2; while(n! =1) { intf=0; while(n%d==0) { f=1; n=n/d; } if(f) ans*=(double)(1-(double)1/(double)d); if(d==2)d++; elsed+=2; } printf("%.0lf\n",ans); } } return0; } 三、数据结构 3.1、最小代价生成树—普利姆算法 floatprim(intn)/*n是顶点的个数,然后所有的顶点之间的距离保存在matrix中间*/ { floatlowcost[101]; booluset[101]={true}; inti,j,k,t; floatmin,sum=0; for(i=0;i { lowcost[i]=matrix[0][i]; } k=0; for(i=1;i { min=INT_MAX; for(j=0;j { if(lowcost[j] uset[j]) { min=lowcost[j]; t=j; } } sum+=min; uset[t]=true; k=t; for(j=0;j { if(! uset[j]&&lowcost[j] { lowcost[j]=matrix[k][j]; } } } returnsum; } 四、动态规划 4.1、LIS最长不下降序列的算法 #include #defineMAX50 intnum[MAX]; intresult[MAX]; intLongest_Increasing(intnum[],intn)//输入数组和其长度,result存放结果数组,返回结果长度 { intlis[MAX],i,j; for(i=0;i { lis[i]=1; for(j=0;j if(num[i]>num[j]&&lis[j]+1>lis[i]) lis[i]=lis[j]+1; } intmaxn=0; for(i=0;i if(maxn maxn=lis[i]; intmax=maxn; for(i=MAX-1;i>=0;i--) { if(lis[i]==maxn) { result[maxn-1]=num[i]; maxn--; } } returnmax; } #include #include intmax; #definemax100020 inta[max]; intB[max]; intresult[max]; intlen; intLIS(intd[],intn)//输入数组和其长度,result存放结果数组,返回结果长度,下标1开始 { memset(B,0,sizeof(B)); intleft,right,mid,i,j; len=1; B[1]=d[1]; for(i=2;i<=n;++i) { left=1,right=len; while(left<=right) { mid=(left+right)/2; if(B[mid] else right=mid-1; } B[left]=d[i]; if(left>len) len++; } for(i=1;i { for(j=1;j { if(a[j]>=B[i]&&a[j]<=B[i+1]) { result[i]=a[j]; break; } } } result[i]=B[i]; returnlen; } intmain() { intn,i,t; scanf("%d",&t); while(t--&&scanf("%d",&n)) { for(i=1;i<=n;i++) scanf("%d",&a[i]); printf("%d\n",LIS(a,n)); for(i=1;i<=len;i++) { printf("%d",result[i]); } } return0; } 4.2、交通最短路径算法 intM[7][7]= { 0,5,2,0,0,0,0, 0,0,0,3,2,0,0, 0,0,0,0,7,4,0, 0,0,0,0,0,0,4, 0,0,0,0,0,0,3, 0,0,0,0,0,0,5, 0,0,0,0,0,0,0 }; intsum=0,min=10000; intMD(intplace)//place是到达的最末端,以此开始往前推,M数组是全局变量,存放每个点之间的关系 { inti,j; i=place; if(i<=0) { if(sum min=sum; return0; } for(j=0;j { if(M[j][i]! =0) { sum+=M[j][i]; MD(j); sum-=M[j][i]; } } return0; } 4.3、数塔最大值算法 voidsolve(inti,intj)//i,j是数塔起始的坐标,a数组是全局定义用来储存数据的数组,max是最大值,s不断变化的和,也是全局变量 { k=0; s=s+a[i][j]; max=max>s? max: s; while(i { solve(i+1,j); s=s-a[i+1][j]; solve(i+1,j+1); s=s-a[i+1][j+1]; break; } } 4.4、最小代价字母树 intdp(intnum[],intlength)//储存数组的数字和该数组的长度 { quickSort(num,0,length-1); if(num[1]==10000) return0; sum=num[0]+num[1]; result+=sum; num[0]=num[1]+num[0];
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ACM 程序 算法 模板
![提示](https://static.bdocx.com/images/bang_tan.gif)