return;
}
高精度阶乘
高精度阶乘求和(秦九韶算法)
varn:
integer;s:
comp;
functionfac(n:
integer):
comp;
begin
whilen>1do
begin
s:
=s*n+1;
dec(n);
end;
fac:
=s;
end;
begin
read(n);
s:
=1;
writeln(fac(n):
0:
0);
end.
{说明:
本程序基于秦九韶算法,大大减少了乘法的计算次数,优于利用递归求阶乘然后求和的方法。
}
typeary=array[0..100]ofinteger;
var
n,i,last:
integer;
s:
ary;
proceduremult(n:
integer;vars:
ary);
begin
s[1]:
=s[1]*n;
fori:
=2tolastdo
begin
s[i]:
=s[i]*n;
s[i]:
=s[i]+s[i-1]div10;
s[i-1]:
=s[i-1]mod10;
end;
whiles[last]>=10do
begin
inc(last);
s[last]:
=s[last-1]div10;
s[last-1]:
=s[last-1]mod10;
end;
end;
procedureadd(vars:
ary);
begin
s[1]:
=s[1]+1;
i:
=1;
whiles[i]>10do
begin
s[i+1]:
=s[i+1]+s[i]div10;
s[i]:
=s[i]mod10;
end;
ifi>lasttheninc(last);
end;
procedurefac(n:
integer);
begin
whilen>1do
begin
mult(n,s);
add(s);
dec(n);
end;
end;
begin
read(n);
last:
=2;s[1]:
=1;
fac(n);
fori:
=lastdownto1dowrite(s[i]);
end.
{说明:
本程序基于秦九韶算法,大大减少了乘法的计算次数,优于利用递归求阶乘然后求和的方法。
}
快速幂算法(分治)
整型快速幂代码(n为底数,k为指数):
intQM(intn,intk)
{
inttmp=n,res=1;
while(k!
=0)
{
if(k&1)res*=tmp;
tmp*=tmp;
k=k>>1;
}
returnres;
}
先将底数转化为高精度数,然后只要将上面的整型全部替换为高精度数即可。
代码如下:
幂为整型:
voidQM_int(hpa,intk,hp&b)
{
hptmp,res;
memcpy(tmp,a,sizeof(tmp));//复制底数
memset(res,0,sizeof(res));//清零
res[0]=res[1]=1;
while(k!
=0)
{
if(k&1)mul_hp(res,tmp,res);
mul_hp(tmp,tmp,tmp);
k=k>>1;
}
memcpy(b,res,sizeof(b));
return;
}
幂为高精度(十进制):
voidQM_int(hpa,hp&k,hp&b)
{
hptmp,res;
memcpy(tmp,a,sizeof(tmp));//复制底数
memset(res,0,sizeof(res));//清零
res[0]=res[1]=1;
while(k[0]!
=1||k[1]!
=0)
{
if(change_div_int(k,2,k,10))mul_hp(res,tmp,res);
mul_hp(tmp,tmp,tmp);
}
memcpy(b,res,sizeof(b));
return;
}
排序算法
冒泡排序
vari,j,k:
longint;
fori:
=1ton-1do
forj:
=i+1tondo
ifa[i]>a[j]thenbegin
k:
=a[i];a[i]:
=a[j];a[j]:
=k;end;
插入排序
varkey,i,j:
longint;
forj:
=2tondobegin
key:
=a[j];i:
=j-1;
while(i>0)and(a[i]>key)do
begina[i+1]:
=a[i];dec(i);end;
a[i+1]:
=key;end;
合并排序
var
l,r:
array[1..6238]oflongint;
q,n1,n2,k:
longint;
ifp=(p+c)shr1elseexit;
sort(p,q);
sort(q+1,c);
n1:
=q-p+1;
n2:
=c-q;
fillchar(l,sizeof(l),0);
fillchar(r,sizeof(r),0);
fori:
=1ton1dol[i]:
=a[p+i-1];
forj:
=1ton2dor[j]:
=a[q+j];
l[n1+1]:
=655360;
r[n2+1]:
=655360;
i:
=1;j:
=1;
fork:
=ptocdo
ifl[i]<=r[j]then
begina[k]:
=l[i];inc(i);end
else
begina[k]:
=r[j];inc(j);end;
快速排序
var
i,j,x,temp:
longint;
i:
=s;j:
=t;x:
=a[(i+j)div2];
repeat
whilea[i]whilea[j]>xdodec(j);{找右边比他小的}
ifi<=jthen{交换}
begin
temp:
=a[i];a[i]:
=a[j];a[j]:
=temp;
inc(i);dec(j);
end;
untili>j;
ifsifi数论算法
辗转相除法(最大公约数,最小公倍数)
functiongcd(x,y:
longint):
longint;
begin
ify=0thengcd:
=xelsegcd:
=gcd(y,xmody);
end;
素数(筛法)
素数测试
欧拉函数
组合算法
组合数计算
functioncc(a,b:
integer):
qword;
var
i,j:
integer;
c:
array[0..32,0..32]ofqword;
begin
fillchar(c,sizeof(c),0);
fori:
=0to30doc[0,i]:
=1;
fori:
=1toado
forj:
=0tobdo
c[i,j+1]:
=c[i,j]+c[i-1,j];
cc:
=c[a,b];
end;
排列数计算
组合生成算法
排列生成算法
卡特兰数
树和图的算法
前序+中序=>后序
proceduretree(s1,s2:
string);
vark:
integer;
begin
iflength(s2)=1then
write(s2)
else
begin
k:
=pos(s2[length(s2)],s1);
write(s1[k]);
ifk>1then
tree(copy(s1,1,k-1),copy(s2,1,k-1));
ifktree(copy(s1,k+1,length(s1)-k),copy(s2,k,length(s2)-k));
end;
end;
前序+中序=>后序
前序+后序=>中序
二叉树遍历
查找算法
顺序查找
二分查找
动态规划
0/1背包
贪心算法
部分背包
搜索算法
0/1背包
参考文献:
《数组型高精度数详解》ByNettle
《算法导论》