ACM培训第一次Word文档下载推荐.docx
- 文档编号:20427320
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:29
- 大小:84.39KB
ACM培训第一次Word文档下载推荐.docx
《ACM培训第一次Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《ACM培训第一次Word文档下载推荐.docx(29页珍藏版)》请在冰豆网上搜索。
fac:
=n*fac(n-1);
end;
readln(n);
writeln(fac(n):
3:
0);
end.
总结:
1、递归一般用函数或过程来实现,主程序没有办法来实现递归;
2、递归要有空间想象能力;
3、需要保护的变量一定要开成局部变量。
像functionfac(n:
integer)中的n.就是局部变量。
2、斐波那契数列
f(n)=f(n-1)+f(n-2)
functionf(n:
integer):
if(n=1)or(n=0)thenbeginf:
f(n):
=f(n-1)+f(n-2);
write(f(n));
end.总结:
(1)递归每执行一次,就要开辟一次局部变量,保护上一次的内容。
递归是逆向出发,先从全局出发,如何将大规模转化为小规模的问题。
(2)fac(4):
=fac(3)+fac
(2);
fac(3):
=fac
(2)+fac
(1);
Fac
(2):
=fac
(1)+fac(0)
重复运算多,速度慢。
3、输入一串字符,以’.’结束,倒序输出。
var
c:
char;
procedureprint(n:
char);
ch:
ifn=’.’thenexit;
readln(ch);
print(ch);
writeln(ch);
begin
readln(c);
print(c)
end.
4、求两个整数的最大公约数(辗转相除法)
程序如下:
m,n:
integer;
functionfac(I,j:
ifj=0thenbeginfac:
=i;
=fac(j,imodj);
readln(n,m);
writeln(fac(n,m));
5、求给出一个多位整数的第K位。
Fac:
=fac(xdiv10,k-1)(k>
1)
Fac(x,k)=
=xmod10(k=1)
x,k:
integer;
functionfac(I,j:
integer):
ifj=1thenbeginfac:
=Imod10;
=fac(Idiv10,k-1);
readln(x,k);
write(fac(x,k));
6、梵诺塔
Var
N:
sa,sb,sc:
string;
Proceduremove(n:
a,b,c:
varsa,sb,sc:
);
Begin
Ifn=1thenbeginwrite(A,’:
’,sa[1],’-)’,C);
Sc:
=sa[1]+sc;
Sa:
=copy(sa,2,length(sa)-1);
Move(n-1,a,c,b,sa,sc,sb);
Write(A,’:
’,sa[1],’-)’,C);
Sc:
Sa:
=copy(sa,2,length(sa)-1);
Move(n-1,b,a,c,sb,sa,sc);
End;
Readln(n);
sa:
=’12345’;
sb:
=’’;
sc:
Move(5,’A’,’B’,’C’,sa,sb,sc);
End.
第二课排列
(排列)
递归跟多重for循环一样,只不过递归可以随机控制循环的层数,可以实现循环次数的可变性,m叫递归的层数,叫深度。
N叫宽度,时间的复杂度为nm次。
控制循环的I一定是局部变量。
1、从n个自然数中取出m个数的排列(允许重复);
var
a:
array[1..100]ofinteger;
n,m,s:
procedureprint;
I:
ForI:
=1tomdo
Write(a[I]:
3);
procedureplay(k:
integer)
Ifk=m+1thenbegin
Inc(s);
Print;
Exit;
End;
=1tondo
Begin
A[k]:
=I;
Play(k+1);
readln(n,m);
s:
=0;
play
(1);
writeln(s);
2、n个自然数中取出m个数的排列(不允许重复(n>
=m);
b:
array[1..100]ofBoolean;
I:
ForI:
integer);
ifk=m+1thenbegininc(s);
print;
forI:
ifb[I]thenbegina[k]:
b[I]:
=false;
play(k+1);
=true;
readln(n,m);
s:
fillchar(b,sizeof(b),false);
play
(1);
writeln(s);
3.限定次数,若干限定次数,即每个数都有限定次数,可用标志数组,B数组先录入限定的次数,用一次则该数组中的数减1,至到为0为止。
4.若干个不连续的数的排列
引入第3个数组C,将不规律映射到规律下标的数组当中。
例:
’PASCAL’字符串取3个字母的排列
*本题就是限次,而且不连续数的排列,可以映射到字符串去。
a:
array[1..3]ofchar;
b:
array[1..26]ofinteger;
p,c:
I,s:
Procedureprint;
=1to3do
Write(a[I]);
Writeln;
Procedureplay(k:
integer);
Var
Ifk=4thenbegininc(s);
exit;
=1tolength(c)do
Ifb[I]>
0thenbegin
=c[I];
Dec(b[I]);
Inc(b[I]);
Readln(p);
C:
=1tolength(p)do
Ifpos(p[I],c)=0thenbeginc:
=c+p[I];
b[pos(p[i],c)]:
Endelseinc(b[pos(p[I],c)];
S:
Play
(1);
Writeln(s);
End.
第三课经典排列
1、错排:
n封信,n个信封,全装错的情况
(I<
>
j,且不允许重复的情况)
array[1..100]ofboolean;
n,s:
procedureprint;
i:
fori:
write(a[i]:
writeln;
procedureplay(k:
ifk=n+1thenbeginprint;
inc(s);
if(i<
k)andb[i]thenbegin
a[k]:
b[i]:
b[i]:
fillchar(b,sizeof(b),true);
2、8皇后问题(任一皇后不在同一行同一列,同一斜行上)
八皇后是一个二维数组,如果用一个一维数组来存放,就可以保证行上不重,在列上再用一个数来判重,就可以保证列上不重。
a,b:
array[1..8]of0..8;
s,n:
functioncan(k:
boolean;
nrep:
=1tok-1do
ifabs(i-k)=abs(a[i]-a[k])thenexit;
i,j:
=1to8dobegin
forj:
=1to8do
ifa[i]=jthenwrite('
*'
:
2)elsewrite(0:
2);
writeln('
----------------------'
proceduretry(k:
ifk>
nthenbegininc(s);
ifb[i]=0thenbegin
ifcan(k)thentry(k+1);
=8;
try
(1);
3、由A、B、C三个字母组成长度为n的没有连续3个相同的子串。
(只讨论第k个字母加上去后是否影响到产生三个相同的子串)
type
str=string[10];
functionnrep(p:
string):
=1tolength(p)div3do
if(copy(p,length(p)-i+1,i)=copy(p,length(p)-2*i+1,i))and
(copy(p,length(p)-2*i+1,i)=copy(p,length(p)-3*i+1,i))then
proceduretry(p:
str);
iflength(p)>
writeln(p);
='
a'
to'
c'
do
ifnrep(p+i)thentry(p+i);
try('
'
4、九连环
(九连环的移动规则:
1、第1位可以随意变;
2、第i位改变时,只要i-1位为0,前面各位都为1,则本位可变。
)
c:
char);
ifa[k]=cthenexit;
ifk=1thena[k]:
=celsebegin
play(k-1,'
0'
=k-2downto1do
play(i,'
1'
=c;
writeln(a);
readln(a);
readln(b);
=length(a)downto1do
play(i,b[i]);
组合问题
(1)
1、从n个自然数中取m个数的组合;
array[0..100]ofinteger;
4);
mthenbegininc(s);
=a[k-1]+1tondo
try(k+1);
a[0]:
2.输入一个正整数,拆分成正整数的和,求所有的情况。
(是组合问题,但允许重复)
procedureprint(k:
write(n,'
a[1]);
=2tokdo
write('
+'
a[i]);
proceduretry(k,p:
ifp=0thenbeginprint(k-1);
=p;
try(k+1,0);
=a[k-1]topdiv2do
begina[k]:
try(k+1,p-i);
try(1,n);
3.分解质因数
functionyes(p:
yes:
=2totrunc(sqrt(p))do
ifpmodi=0thenexit;
procedureplay(k,p:
ifp=1thenbeginprint(k-1);
ifyes(p)thenbegina[k]:
play(k+1,1);
=a[k-1]totrunc(sqrt(p))do
if(i>
1)and(pmodi=0)thenbegina[k]:
play(k+1,pdivi);
=2;
play(1,n);
第四次课深度搜索
在我们遇到的一些问题当中,有些问题我们不能够确切的找出数学模型,即找不出一种直接求解的方法,解决这一类问题,我们一般采用搜索的方法解决。
搜索就是用问题的所有可能去试探,按照一定的顺序、规则,不断去试探,直到找到问题的解,试完了也没有找到解,那就是无解,试探时一定要试探完所有的情况(实际上就是穷举);
对于问题的第一个状态,叫初始状态,要求的状态叫目标状态。
搜索就是把规则应用于实始状态,在其产生的状态中,直到得到一个目标状态为止。
产生新的状态的过程叫扩展(由一个状态,应用规则,产生新状态的过程)
搜索的要点:
(1)初始状态;
(2)重复产生新状态;
(3)检查新状态是否为目标,是结束,否转
(2);
如果搜索是以接近起始状态的程序依次扩展状态的,叫宽度优先搜索。
如果扩展是首先扩展新产生的状态,则叫深度优先搜索。
深度优先搜索
深度优先搜索用一个数组存放产生的所有状态。
(1)把初始状态放入数组中,设为当前状态;
(2)扩展当前的状态,产生一个新的状态放入数组中,同时把新产生的状态设为当前状态;
(3)判断当前状态是否和前面的重复,如果重复则回到上一个状态,产生它的另一状态;
(4)判断当前状态是否为目标状态,如果是目标,则找到一个解答,结束算法。
(5)如果数组为空,说明无解。
(6)转到(2)
对于pascal语言来讲,它支持递归,在递归时可以自动实现回溯(利用局部变量)所以使用递归编写深度优先搜索程序相对简单,当然也有非递归实现的算法。
1、迷宫
const
d:
array[1..4,1..4]ofinteger=((1,1,0,0),(0,1,1,1),(1,1,0,1),(0,1,1,1));
array[1..4,1..2]of-1..1=((0,1),(0,-1),(1,0),(-1,0));
array[1..16,1..2]ofinteger;
if(a[k,1]=4)and(a[k,2]=4)then
=1tokdo
('
a[i,1],'
'
a[i,2],'
)'
readln;
=1to4do
if(a[k,1]+c[i,1]>
0)and(a[k,1]+c[i,1]<
5)and(a[k,2]+c[i,2]>
0)and(a[k,2]+c[i,2]<
5)then
ifd[a[k,1],a[k,2]]=1thenbegin
d[a[k,1],a[k,2]]:
a[k+1,1]:
=a[k,1]+c[i,1];
a[k+1,2]:
=a[k,2]+c[i,2];
fillchar(a,sizeof(a),0);
a[1,1]:
a[1,2]:
2、8数码
type
node=array[1..3,1..3]of0..8;
st:
node=((2,8,3),(1,6,4),(7,0,5));
gl:
node=((1,2,3),(8,0,4),(7,6,5));
rl:
array[1..4,1..2]of-1..1=((0,1),(0,-1),(1,0),(-1,0));
array[1..20]ofnode;
functionresult(k:
i,x,y:
result:
forx:
fory:
ifa[k,x,y]<
gl[x,y]thenexit;
procedurelook(k:
varx,y:
ifa[k,i,j]=0thenbeginx:
y:
=j;
step:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ACM 培训 第一次