NOIP复赛必记常用算法.docx

上传人:b****8 文档编号:30499969 上传时间:2023-08-16 格式:DOCX 页数:55 大小:30.03KB
下载 相关 举报
NOIP复赛必记常用算法.docx_第1页
第1页 / 共55页
NOIP复赛必记常用算法.docx_第2页
第2页 / 共55页
NOIP复赛必记常用算法.docx_第3页
第3页 / 共55页
NOIP复赛必记常用算法.docx_第4页
第4页 / 共55页
NOIP复赛必记常用算法.docx_第5页
第5页 / 共55页
点击查看更多>>
下载资源
资源描述

NOIP复赛必记常用算法.docx

《NOIP复赛必记常用算法.docx》由会员分享,可在线阅读,更多相关《NOIP复赛必记常用算法.docx(55页珍藏版)》请在冰豆网上搜索。

NOIP复赛必记常用算法.docx

NOIP复赛必记常用算法

2.小范围内判断一个数是否为质数:

functionprime(n:

integer):

boolean;

varI:

integer;

begin

forI:

=2totrunc(sqrt(n))do

ifnmodI=0thenbegin

prime:

=false;exit;

end;

prime:

=true;

end;

1折半查找(二分法查找)

functionbinsearch(k:

keytype):

integer;

varlow,hig,mid:

integer;

begin

low:

=1;hig:

=n;

mid:

=(low+hig)div2;

while(a[mid].key<>k)and(low<=hig)do

begin

ifa[mid].key>kthenhig:

=mid-1

elselow:

=mid+1;

mid:

=(low+hig)div2;

end;

iflow>higthenmid:

=0;

binsearch:

=mid;

end;

冒泡法排序

fori:

=1ton-1do

forj:

=i+1tondo

ifb[i]>b[j]then

begink:

=b[i];b[i]:

=b[j];b[j]:

=k;end;

找出3-100之间的所有素数

forn:

=3to100do

begin

f:

=true;

fori:

=2ton-1doifnmodi=0thenf:

=false;

iff=truethenwrite(n:

5);

end;

.冒泡排序另一种写法

fori:

=1ton-1do

forj:

=ndowntoi+1do

ifa[j]

选择法排序

fori:

=1ton-1do

begink:

=i;

forj:

=i+1to10do

ifb[j]

=j;

ifk<>ithenbegint:

=b[k];b[k]:

=b[i];b[i]:

=t;end;

write(b[i]:

3);

end;writeln(b[n]:

3);

procedureqsort(l,r:

integer);//快速排序

vari,j,mid:

integer;

begin

i:

=l;j:

=r;mid:

=a[(l+r)div2];{将当前序列在中间位置的数定义为中间数}

repeat

whilea

whilea[j]>middodec(j);{在右半部分寻找比中间数小的数}

ifi<=jthenbegin{若找到一组与排序目标不一致的数对则交换它们}

swap(a,a[j]);

inc(i);dec(j);{继续找}

end;

untili>j;

ifl

ifi

end;{sort}

procedureinsertsort;插入法排序

vari,j,k:

integer;

f:

boolean;

begin

b[1]:

=a[1];

fori:

=2to10do

begin

j:

=1;f:

=false;

while(j<=i-1)and(notf)do

ifa[i]

begin

fork:

=idowntoj+1dob[k]:

=b[k-1];

b[j]:

=a[i];f:

=true;

end

elsej:

=j+1;

ifnotfthenb[i]:

=a[i];

end;

fori:

=1to10dowrite(b[i]:

3);

writeln;

end;

高精度数的定义:

type

hp=array[1..maxlen]ofinteger;

1.高精度加法

procedureplus(a,b:

hp;varc:

hp);

vari,len:

integer;

begin

fillchar(c,sizeof(c),0);ifa[0]>b[0]thenlen:

=a[0]elselen:

=b[0];

fori:

=1tolendobegin

inc(c,a+b);

ifc>10thenbegindec(c,10);inc(c[i+1]);end;{进位}

ifc[len+1]>0theninc(len);

c[0]:

=len;

end;{plus}

3.高精度乘以低精度

proceduremultiply(a:

hp;b:

longint;varc:

hp);

vari,len:

integer;

begin

fillchar(c,sizeof(c),0);

len:

=a[0];

fori:

=1tolendobegin

inc(c,a*b);

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

c:

=cmod10;

end;

inc(len);

while(c[len]>=10)dobegin{处理最高位的进位}

c[len+1]:

=c[len]div10;

c[len]:

=c[len]mod10;

inc(len);

end;

while(len>1)and(c[len]=0)dodec(len);{若不需进位则调整len}

c[0]:

=len;

end;{multiply}

4.高精度乘以高精度

procedurehigh_multiply(a,b:

hp;varc:

hp}

vari,j,len:

integer;

begin

fillchar(c,sizeof(c),0);

fori:

=1toa[0]do

forj:

=1tob[0]dobegin

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

inc(c[i+j],c[i+j-1]div10);

c[i+j-1]:

=c[i+j-1]mod10;

end;

len:

=a[0]+b[0]+1;

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

c[0]:

=len;

end;

proceduredevide(a:

hp;b:

longint;varc:

hp;vard:

longint);

{c:

=adivb;d:

=amodb}

vari,len:

integer;

begin

fillchar(c,sizeof(c),0);

len:

=a[0];d:

=0;

fori:

=lendownto1dobegin

d:

=d*10+a;

c:

=ddivb;

d:

=dmodb;

end;

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

c[0]:

=len;

end;

2.高精度减法

proceduresubstract(a,b:

hp;varc:

hp);

vari,len:

integer;

begin

fillchar(c,sizeof(c),0);

ifa[0]>b[0]thenlen:

=a[0]elselen:

=b[0];

fori:

=1tolendobegin

inc(c,a-b);

ifc<0thenbegininc(c,10);dec(c[i+1]);end;

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

c[0]:

=len;

end;

6.高精度除以高精度

procedurehigh_devide(a,b:

hp;varc,d:

hp);

var

i,len:

integer;

begin

fillchar(c,sizeof(c),0);

fillchar(d,sizeof(d),0);

len:

=a[0];d[0]:

=1;

fori:

=lendownto1dobegin

multiply(d,10,d);

d[1]:

=a;

while(compare(d,b)>=0)do{即d>=b}

begin

Subtract(d,b,d);

inc(c);

end;

end;

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

c.len:

=len;

end;

5.高精度除以低精度

proceduredevide(a:

hp;b:

longint;varc:

hp;vard:

longint);

{c:

=adivb;d:

=amodb}

vari,len:

integer;

begin

fillchar(c,sizeof(c),0);

len:

=a[0];d:

=0;

fori:

=lendownto1dobegin

d:

=d*10+a;

c:

=ddivb;

d:

=dmodb;

end;

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

c[0]:

=len;

end;

programsdss_8hh(input,output);

labelss,hs;{说明两个标号}

varh,g:

array[1..8]ofinteger;{h数组存每行皇后所在列数,g数组存每行皇后已试放过的列数}

t,i,s:

integer;

begin

fori:

=1to8doh[i]:

=0;t:

=1;s:

=0;{开始搜索}

repeat

ss:

g[t]:

=g[t]+1;{方向数增1}

ifg[t]>8thengotohs;{若超过允许的8个方向则回嗍}

fori:

=1tot-1do{否则检验1行到8行的皇后是否与本行皇后处在同一列或同一斜线上}

if(h[i]=g[t])or(abs(i-t)=abs(g[t]-h[i]))thengotoss;{若在同一列或同一斜线上则重新换向搜索}

h[t]:

=g[t];{否则保存该行皇后的列位置}

t:

=t+1;{前进一步}

untilt>8;{直到第8行}

fori:

=1to8dowrite(h[i]:

2);{打印本方案}

s:

=s+1;writeln('---',s);

t:

=8;{从第8行开始回嗍}

hs:

g[t]:

=0;{t步方向清零}

t:

=t-1;{回嗍一步}

ift>0thengotoss;{若未到起点则继续转搜索}

writeln('end');

end.

programtm(output);跳马问题深度搜索

labelss,hs;

typesz=array[0..4,0..8]ofinteger;

varg:

array[1..50]ofinteger;{大约在50步以内完成}

a,b:

array[1..4]ofinteger;{a,b是4个方向上的坐标的行、列增量数组}

m:

array[1..50,1..2]ofinteger;{m数组存路线上各点的坐标}

p:

sz;{p数组记录棋盘上各点是第几步走到的}

i,j,t,x,y,s,hn,ln:

integer;

procedurepr(h:

sz;hn,ln:

integer);{打印每一种方案中的p数组}

vari,j:

integer;

begin

fori:

=0tohndo

beginforj:

=0tolndo

ifh[i,j]<>0thenwrite(h[i,j]:

3)

elsewrite('-':

3);writeln;

end;writeln('---------------------------------------');

end;

begin{main}

{clrscr;}

write('hn,ln=');

readln(hn,ln);{设定棋盘的行、列数,此处一般输入4,8}

fori:

=0tohndo

forj:

=0tolndop[i,j]:

=0;

writeln('t=0');

pr(p,hn,ln);

a[1]:

=2;b[1]:

=1;{b[]---liezenlianga[]---hangzenliang}

a[2]:

=1;b[2]:

=2;

a[3]:

=-1;b[3]:

=2;

a[4]:

=-2;b[4]:

=1;

t:

=1;s:

=0;x:

=0;y:

=0;m[t,1]:

=x;m[t,2]:

=y;p[hn-x,y]:

=t;{搜索初始化}

writeln('t=',t);pr(p,hn,ln);

ss:

{开始搜索}

repeat

g[t]:

=g[t]+1;{方向数增1}

ifg[t]>4thengotohs;{若方向超界,则换向搜索}

i:

=x+a[g[t]];j:

=y+b[g[t]];{若未超界,则按此步试探的方向生成下一步可能的落脚点坐标}

if(i<=hn)and(i>=0)and(j<=ln)and(j>=0)then{若该点在棋盘内,则前进一步,保存该点坐标和步数}

begin

t:

=t+1;

m[t,1]:

=i;m[t,2]:

=j;

x:

=i;y:

=j;

p[hn-x,y]:

=t;

end;

until(x=hn)and(y=ln);{直到到达右上角为止}

{print}

fori:

=1totdowrite('(',m[i,1],',',m[i,2],')->');{打印这条路径}

s:

=s+1;

writeln(t,'====',s);

pr(p,hn,ln);{调用过程打印该路径对应的棋盘路线图}

readln;{本句目的使运行结果由手工控制,按一次回车,出一个结果}

hs:

{开始回溯}

p[hn-x,y]:

=0;{最后一步的p数组元素置零}

g[t]:

=0;{最后一步方向清零}

t:

=t-1;{回溯一步}

ift>0thenbeginx:

=m[t,1];y:

=m[t,2];gotoss;end{若未到起点,则调出第t步的坐标x,y然后转搜索}

else{否则可行方案寻找完毕}

writeln('end')

end.

programqpl(input,output);全排列问题的深度搜索

labelss,hs;

vara,fx,b:

array[1..30]ofinteger;{a数组存每一步搜索到的字母,fx数据存每一步试探过的方向数,b数组作标志(该字母被用过否}

t,j,k,total,n:

integer;{t搜索深度,n排列字母的个数,total总方案数}

begin

write('inputn=');readln(n);

t:

=1;total:

=0;{搜索的初始状态}{开始搜索}

repeat

ss:

fx[t]:

=fx[t]+1;{方向数增1}

iffx[t]>nthengotohs;{若方向数超界则回溯}

ifb[fx[t]]=1thengotoss;{未超界,但该字母被用过也要重新搜索}

a[t]:

=fx[t];{该字母可用,保存到a数组中,该字母标志置1,表示已被用}

b[fx[t]]:

=1;

t:

=t+1;{前进一步,搜索下一位置的字母}

untilt>n;{直到n个字母都搜索出来}

fork:

=1tondowrite(chr(a[k]+64));{打印这一种方案}

total:

=total+1;writeln('---',total);

t:

=n;

b[a[t]]:

=0;{将最后一步用过的字母标志清零(换其它字母看行否),继续搜索}

gotoss;

hs:

{开始回溯}

fx[t]:

=0;{t步用过的方向数清零}

t:

=t-1;{回溯一步}

ift>0thenbegin

b[a[t]]:

=0;{如果未回到起点,就将该步原来用过的字母标志清零,然后转搜索}

gotoss;end;

writeln('end');{否则所有可行方案已搜索完毕,结束}

end.

fori:

=1totdowrite('(',m[i,1],',',m[i,2],')->');{打印这条路径}

s:

=s+1;

writeln(t,'====',s);

pr(p,hn,ln);{调用过程打印该路径对应的棋盘路线图}

readln;{本句目的使运行结果由手工控制,按一次回车,出一个结果}

hs:

{开始回溯}

p[hn-x,y]:

=0;{最后一步的p数组元素置零}

g[t]:

=0;{最后一步方向清零}

t:

=t-1;{回溯一步}

ift>0thenbeginx:

=m[t,1];y:

=m[t,2];gotoss;end{若未到起点,则调出第t步的坐标x,y然后转搜索}

else{否则可行方案寻找完毕}

writeln('end')

end.

proceduremglj(varmg:

mgsz;ruko,chko:

kjl);广度搜索迷宫的过程

varx,y,i,j,v:

integer;

begin

sq[1].h:

=ruko.h;sq[1].l:

=ruko.l;sq[1].pre:

=0;

front:

=1;rear:

=1;mg[1,1]:

=2;{front指向父结点,rear指向该父结点对应的子结点}

whilefront<=reardo{当front超过rear时,表示所有子结点都已发展完,否则就继续向下发展}

begin

x:

=sq[front].h;{x,y表示当前结点位置}

y:

=sq[front].l;

forv:

=1to4do

begin

i:

=x+zl[v].h;{i,j表示可能的子结点位置}

j:

=y+zl[v].l;

ifmg[i,j]=0then{该点有通路,则将其发展为一个子结点}

begin

rear:

=rear+1;{子结点指针增1,并将该子结点的位置及对应父结点的编号记录到队列中}

sq[rear].h:

=i;

sq[rear].l:

=j;

sq[rear].pre:

=front;

mg[i,j]:

=2;{迷宫走过之处置2,作标志,防回头路}

end;

if(i=chko.h)and(j=chko.l)then{如果当前子结点已到出口,则找到了一条通路,打印该路径}

begin

writeln('front=',front);

printlj(sq,rear);

{mg[chko.h,chko.l]:

=0;

rear:

=rear-1;

front:

=sq[sq[front].pre].pre;

restore(mg);

exit;}

end;

end;

front:

=front+1;

end;

writeln('noway');

end;

programtm_gdss(input,output);{广度搜索跳马路径}

typemgsz=array[0..20,0..20]ofinteger;{存棋盘中马跳的各点步数方阵}

sqtype=array[1..400]ofrecord{队列,存放跳马过程中按广度方式发展的各结点坐标和前趋结点号}

h,l:

integer;

pre:

0..400;

end;

kjl=record

h,l:

integer;{入口及出口的行列坐标记录类型}

end;

varmg:

mgsz;

sq:

sqtype;

zl:

array[1..4]ofrecord{马可跳的四个方向行列坐标增量数组}

h,l:

-2..2;

end;

front,rear,i,j,m,n,num:

integer;{front--队列头指针,rear---队列尾指针}

ruko,chko:

kjl;

{入口和出口坐标}

procedureprintlj(sq:

sqtype;rear:

integer);{打印搜索出的一条马跳路径}

vari,j,k:

integer;

begin

fori:

=0tomdo

forj:

=0tondomg[i,j]:

=0;{棋盘方阵清零}

i:

=rear;

k:

=0;

repeat{这一段逆向打印出马跳路径,并统计出所用的步数,该步数将反映出马所跳位置步数}

write('(',sq[i].h,',',sq[i].l,')<--');k:

=k+1;

i:

=sq[i].pre;{沿前趋指针取出前趋结点号}

untili=0;

num:

=num+1;

writeln('==',num);

i:

=rear;

repeat

mg[m-sq[i].h,sq[i].l]:

=k;{重新用K值改换棋盘方阵}

i:

=sq[i].pre;

k:

=k-1;

untili=0;

writeln('------------------------------------');{打印出这种跳法的棋盘方阵}

fori:

=0tomdo

begin

forj:

=0tondowrite(mg[i,j]:

2);

writeln;

end;

end;

proceduretmlj(ruko,chko:

kjl);{广度搜索所有跳马路径}

varx,y,i,j,v:

integer;{x,y---当前结点坐标,i,j---欲发展的子结点坐标,V---每点4个方向的循环变量}

begin

sq[1].h:

=ruko.h;sq[1].l:

=ruko.l;sq[1].pre:

=0;{入口坐标进入队列}

front:

=1;rear:

=1;{队头、队尾指针初始化}

whilefront<=reardo{队头指针未超过队尾指针,则队列还有可发展的结点,继续}

begin

x:

=sq[front].

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

当前位置:首页 > 高中教育 > 英语

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

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