编程基本算法普及组.docx

上传人:b****2 文档编号:12892039 上传时间:2023-04-22 格式:DOCX 页数:17 大小:19.31KB
下载 相关 举报
编程基本算法普及组.docx_第1页
第1页 / 共17页
编程基本算法普及组.docx_第2页
第2页 / 共17页
编程基本算法普及组.docx_第3页
第3页 / 共17页
编程基本算法普及组.docx_第4页
第4页 / 共17页
编程基本算法普及组.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

编程基本算法普及组.docx

《编程基本算法普及组.docx》由会员分享,可在线阅读,更多相关《编程基本算法普及组.docx(17页珍藏版)》请在冰豆网上搜索。

编程基本算法普及组.docx

编程基本算法普及组

编程基本算法(普及组)

ForNOIP2009

ByClimber

Pascal

计算程序运行时间

usesdos;

var

h,m,s,ss:

word;

t1,t2:

real;

begin

gettime(h,m,s,ss);

t1:

=h*3600+m*60+s+ss/100;

****//主程序

gettime(h,m,s,ss);

t2:

=h*3600+m*60+s+ss/100;

writeln((t2-t1):

0:

2);

end.

高精度运算

初始化

【加减法初值】tmp[0]:

=1;

【乘法初值】tmp[0]:

=1;tmp[1]:

=1;

【高精度类型】typehp=array[0..250]ofinteger;//hp[0]表示该数的长度

比较大小(Max)

if(a[0]>b[0])thenmax:

=trueelsemax:

=false;//比较

fori:

=a[0]downto1do

ifa[i]>b[i]thenmax:

=trueelsemax:

=false;

ifmax=falsethenbegintmp:

=a;a:

=b;b=tmp;end;//交换

高精度(a)+整型(b)=高精度(c)

Inc(a[1],b);//相加

while(a[a[0]]>9)dobegin//进位

inc(a[a[0]+1],a[a[0]]div10);

a[a[0]]:

=a[a[0]]mod10;inc(a[0]);end;

dec(a[0]);c:

=a;

高精度(a)-整型(b)=高精度(c)

Whilex<>0dobegin//相减

dec(c[c[0]],xmod10);

x:

=xdiv10;inc(c[0]);end;

fori:

=1toc[0]doifc[i]<0then//退位

begininc(c[i],10);dec(c[i+1]);end;

while(c[c[0]]=0)and(c[0]>1)dodec(c[0]);

高精度(a)×整型(b)=高精度(c)

fori:

=1toa[0]doc[i]:

=a[i]*x;c[0]:

=a[0]+10;

fori:

=1toc[0]doifc[i]>9then

begininc(c[i+1],c[i]);c[i]:

=c[i]mod10;end;

while(c[c[0]]=0)and(c[0]>1)dodec(c[0]);

高精度(a)÷整型(b)=高精度(c)

voiddiv_int(hpa,intx,hp&res,int&rest)

{

memset(res,0,sizeof(res));

rest=0;

for(inti=a[0];i>=1;i--)

{

rest=rest*10+a[i];

if(rest>=x)res[i]=rest/x,rest%=x;

}

intl=a[0];

while(res[l]==0&&l>1)l--;

res[0]=l;

return;

}

高精度(a)+高精度(b)=高精度(c)

fori:

=1toa[0]dotmp[i]:

=a[i]+b[i];//相加

fori:

=1toa[0]+1doifc[i]>9then//进位

begininc(c[i+1]);dec(c[i],10);end;

inc(c[0]);while(c[c[0]]=0)and(c[0]>1)dodec(c[0]);//长度计算

高精度(a)-高精度(b)=高精度(c)

Max(a,b);

fori:

=1toa[0]doc[i]:

=a[i]-b[i];//相减

fori:

=1toa[0]doifc[i]<0then//进位

begindec(c[i+1]);inc(c[i],10);end;

while(c[[c[0]]=0)and(c[0]>1)dodec(c[0]);//长度计算

高精度(a)×高精度(b)=高精度(c)

fori:

=1toa[0]doforj:

=1toa[0]do

inc(c[i+j-1],a[i]*b[j]);

c[0]:

=a[0]+b[0];

fori:

=1toc[0]doifc[i]>9then

begininc(c[i+1],tmp[i]div10);tmp[i]:

=tmp[i]mod10;end;

while(c[c[0]]=0)and(c[0]>1)dodec(c[0]);

高精度(a)÷高精度(b)=高精度(c)

intdiv_hp(hp&a,hp&b,hp&rest)

{

hptmp;

intl=MIN_RES,r=MAX_RES,mid;

while(l<=r)

{

mid=(l+r)/2;

mul_int(b,mid,tmp);

if(compare(a,tmp)==false)r=mid;

else

{

sub_hp(a,tmp,tmp);

if(compare(tmp,b)==true)l=mid;

else

{

memcpy(rest,tmp,sizeof(tmp));

returnmid;

}

}

}

return0;

}

高精度进制转换

首先需要一个改良版的高精度数除整型取余,增加一个k参数表示当前高精度数的进制。

代码如下,返回值为余数:

intchange_div_int(hpa,intx,hp&res,intk)

{

intrest;

hptmp;

memset(tmp,0,sizeof(tmp));

rest=0;

for(inti=a[0];i>=1;i--)

{

rest=rest*k+a[i];

if(rest>=x)tmp[i]=rest/x,rest%=x;

}

intl=a[0];

while(tmp[l]==0&&l>1)l--;

tmp[0]=l;

memcpy(res,tmp,sizeof(tmp));

returnrest;

}

高精度进制转换的主函数,n为当前进制,k为目标进制,b为结果:

voidN_to_K(hp&a,intn,intk,hp&b)

{

memset(b,0,sizeof(b));

while(a[0]!

=1||a[1]!

=0)

{

b[0]++;

b[b[0]]=change_div_int(a,k,a,n);

}

return;

}

压位高精度

voidInit(hp&a)

{

strings;

inttmp=0,t=0,l,k;

cin>>s;

memset(a,0,sizeof(a));

l=s.size();

k=l/8;

if(l%8!

=0)k++;

a[0]=k;

for(inti=1;i

{

t=l-8*i;

tmp=0;

for(intj=0;j<=7;j++)

tmp=tmp*10+(s[t+j]-'0');

a[i]=tmp;

}

l=l-(a[0]-1)*8,tmp=0;

for(intt=0;t

tmp=tmp*10+s[t]-'0';

a[a[0]]=tmp;

return;

}

voidadd(hpa,hpb,hp&c)

{

intl=max(a[0],b[0]);

hptmp;

memset(tmp,0,sizeof(tmp));

for(inti=1;i<=l;i++)

tmp[i]=a[i]+b[i];

for(inti=1;i<=l;i++)

if(tmp[i]>=0)

tmp[i+1]++,tmp[i]-=0;

l++;

while(tmp[l]==0&&l>1)l--;

tmp[0]=l;

memcpy(c,tmp,sizeof(c));

return;

}

voidZero(intx)//补零

{

if(x<10){cout<<"0000000";return;}

if(x<100){cout<<"000000";return;}

if(x<1000){cout<<"00000";return;}

if(x<10000){cout<<"0000";return;}

if(x<100000){cout<<"000";return;}

if(x<1000000){cout<<"00";return;}

if(x<){cout<<"0";return;}

return;

}

voidprin(hpa)

{

cout<

for(inti=a[0]-1;i>=1;i--)

{Zero(a[i]);cout<

cout<

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;

ifs

ifi

数论算法

辗转相除法(最大公约数,最小公倍数)

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));

ifk

tree(copy(s1,k+1,length(s1)-k),copy(s2,k,length(s2)-k));

end;

end;

前序+中序=>后序

前序+后序=>中序

二叉树遍历

查找算法

顺序查找

二分查找

动态规划

0/1背包

贪心算法

部分背包

搜索算法

0/1背包

参考文献:

《数组型高精度数详解》ByNettle

《算法导论》

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 成人教育 > 自考

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

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