初三计算机竞赛练习九回溯算法答案.docx
《初三计算机竞赛练习九回溯算法答案.docx》由会员分享,可在线阅读,更多相关《初三计算机竞赛练习九回溯算法答案.docx(23页珍藏版)》请在冰豆网上搜索。
初三计算机竞赛练习九回溯算法答案
初三计算机竞赛练习九——回溯算法
1、[问题描述]
把1-3这3个数字按照不同顺序排列,求有多少种排列方式?
Programe3;
var
A,U:
array[1..100]ofInteger;
n,I,Count:
Integer;
procedureSearch(Depth:
Integer);
var
i:
Integer;
begin
ifDepth<=nthen
begin
fori:
=1tondo
ifU[i]=0then
begin
U[i]:
=1;
A[Depth]:
=i;
Search(Depth+1);
U[i]:
=0;
end;
end
elsebegin
fori:
=1tondo
Write(A[i],'');
Writeln;
end;
end;
begin
Readln(n);
fori:
=1tondo
U[i]:
=0;
Count:
=0;
Search
(1);
Writeln(Count);
end.
2、[问题描述]
有一个m*n的迷宫地图,0表示通路,1表示障碍物。
现在请你找出一条从左上角走到右下角的路径。
Programe4;
const
dx:
array[1..4]ofInteger=(-1,0,1,0);
dy:
array[1..4]ofInteger=(0,-1,0,1);
var
A,U:
array[1..20,1..20]ofInteger;
Path:
array[1..400,1..2]ofInteger;
m,n,i,j:
Integer;
Found:
Boolean;
procedurePrint(Depth:
Integer);
var
i:
Integer;
begin
fori:
=1toDepthdo
Writeln(Path[i][1],‘‘,Path[i][2]);
Found:
=True;
end;
procedureSearch(Depth:
Integer;x,y:
Integer);
var
i,nx,ny:
Integer;
begin
Path[Depth][1]:
=x;Path[Depth][2]:
=y;
U[x,y]:
=1;
if(x=m)and(y=n)thenPrint(Depth)
elsebegin
fori:
=1to4do
begin
nx:
=x+dx[i];ny:
=y+dy[i];
if(nx>=1)and(nx<=m)and(ny>=1)and(ny<=n)and
(A[nx,ny]=0)and(U[nx,ny]=0)then
begin
Search(Depth+1,nx,ny);
ifFoundthenExit;
end;
end;
end;
end;
begin
Readln(m,n);
fori:
=1tomdo
forj:
=1tondo
begin
Read(A[i,j]);
U[i,j]:
=0;
end;
Found:
=False;
Search(1,1,1);
end.
3、[问题描述]
八皇后问题:
要求在8X8格的国际象棋盘上摆放8个皇后,使其不能互相攻击。
即任意两个皇后都不处于同一行、同一列或同一斜线上,问有多少种摆法。
Programeightqueens;
Var
X:
array[1..8]ofinteger;
A,b,c:
array[-7..16]ofBoolean;
I:
integer;
Procedureprint;
VarK:
integer;
Begin
Fork:
=1to8do
Write(x[k]:
4);
Writeln
End;
Proceduretry(I:
integer);
Var
J:
integer;
Begin
Forj:
=1to8do
Ifa[j]andb[I+j]andc[I-j]
Thenbegin
X[I]:
=j;
A[j]:
=false;
B[I+j]:
=false;
C[I-j]:
=false;
IfI<8
Thentry(I+1)
Elseprint;
A[j]:
=true;
B[I+j]:
=true;
C[I-j]:
=true
End
End;
Begin
ForI:
=-7to16do
Begin
A[I]:
=true;
B[I]:
=true;
C[I]:
=true;
End;
Try
(1)
End.
4、[问题描述]
设有图所示的一个棋盘,在棋盘上的A点,有一个中国象棋的马,并约定马走的规则:
(1)马走日字
(2)马只能向右走
找出一条从A到B的路径
ProgramA201(input,output);
Varx,y,m,k,i:
integer
b:
array[0..8]ofinteger
dx,dy:
array[1..4]ofinteger;
begin
x:
=0;y:
=0
m:
=0;k=0;
dx[1]:
=1;dy[1]:
=-2;
dx[2]:
=2;dy[2]:
=-1;
dx[3]:
=2;dy[3]:
=1;
dx[4]:
=1;dy[4]:
=2;
fori:
=0to8dob[i]:
=0;
while(x<>8)or(y<>4)do
begin
k:
=k+1;
ifk>4then
begin
k:
=b[m];
m:
=m-1;
x:
=x-dx[k];
y:
=y-dy[k];
end
else
begin
x:
=x+dx[k];
y:
=xy+dy[k];
if(x>8)of(y<0)of4)then
begin
x:
=x-dx[k];
y:
=y-dy[k];
end
else
begin
m:
=m+1;
b[m]:
=k;
k:
=0
end
end
end;
fori:
=1tomdowrite(b[i]:
3);
writeln
End.
5、[问题描述]
设有一个nXn的棋盘(n<=10),在棋盘上的任一点A(x,y)有一个中国象棋的马,马走的规则同前,但取消马只能向走的条件。
试找出一条路径,使马不重复地走遍棋盘上的每一个点。
Programa202_a;
Constn1=20;
Varn,x,y,x1,y1,m,k,i:
integer;
A:
array[1..n1,1..n1]of0..1;
B:
array[0..n1*n1]ofinteger;
Dx,dy:
array[1..8]ofinteger;
Cr:
longint;
Begin
Write(‘n=’);
Readln(n);
Write(‘x,y=‘);
Readln(x,y);
M:
=0;k:
=0;
Dx[1]:
=1;dy[1]:
=-2;
Dx[2]:
=2;dy[2]:
=-1;
Dx[3]:
=2;dy[3]:
=1;
Dx[4]:
=1;dy[4]:
=2;
Dx[5]:
=-1;dy[5]:
=2
Dx[6]:
=-2;dx[6]:
=1;
Dx[7]:
=-2;dy[7]:
=-1;
Dx[8]=-1;dy[8]:
=-2;
ForI:
=0ton*ndob[I]:
=0;
Forx1:
=1tondo
Fory1:
=1tondo
A[x1,y1]:
=0;
A[x,y]:
=1;
Cr:
=0;
While(b[0]=0)and(mBegin
K:
=k+1;
Ifk>8then
Begin
A[x,y]:
=0;
K:
=b[m];
M:
=m-1;
X:
=x-dx[k];
Y:
=y-dy[k]
End
Else
Begin
X:
=x+dx[k];
Y:
=y+dy[k];
If(x<1)or(x>n)or(y<1)or(y>n)or(a[x,y]>0)then
Begin
X:
=x-dx[k];
Y:
=y+dy[k];
End
Else
Begin
M:
=m+1;
A[x,y]:
=m+1;
Inc(cr);
B[m]:
=k;
K:
=0
End
End
End;
Fory:
=1tondo
Begin
Forx:
=1tondo
Write(a[x,y]:
3);
Writeln
End;
Writeln(cr);
End.
6、[问题描述]
设有一个nXn方格的迷宫,入口和出口分别在左上角和右上角(如图所示)。
Programa203;
Var
a:
array[1..20,1..20]of0..1;
C:
array[1..20,1..20]of0..1;
B:
array[0..400]ofinteger;
Dx,dy:
array[1..8]ofinteger;
N,m,k,I,x,y:
integer;
Begin
Write(‘n=‘);
Readln(n);
Fory:
=1tondo
Begin
Forx:
=1tondo
Begin
Read(a[x,y]);
C[x,y]:
=0
End;
Readln
End;
Dx[1]:
=1;dy[1]:
=-1;
Dx[2]:
=1;dy[2]:
=0;
Dx[3]:
=-1;dy[3]:
=1;
Dx[4]:
=-1;dy[4]:
=0;
Dx[5]:
=1;dy[5]:
=1;
Dx[6]:
=-1;dy[6]:
-1;
Dx[7]:
=0;dy[7]:
=1;
Dx[8]:
=0;dy[8]:
=-1;
X:
=1;y:
=1;
M:
=0;k:
=0;
ForI:
=0to400dob[I]:
=0;
While(x<>n)or(y<>1)do
Begin
K:
=K+1;
Ifk>8then
Begin
K:
=b[m];
M:
=m-1;
X:
=x-dx[k];
Y:
y-dy[k]
End
Else
Begin
X:
=x+dx[k];
Y:
=y+dy[k];
If(x<1)or(x>n)or(y<1)or(y>n)or(a[x,y]=1)or(c[x,y]=1then
Begin
X:
=x-dx[k];
Y:
=y-dy[k]
End
Else
Begin
M:
=m+1;
C[x,y]:
=1;
B[m]:
=k;
K:
=0
End
End
End;
X:
=1;y:
=1;
Write(‘(‘,x,’,’,y,’)’);
ForI:
=1tomdo
Begin
X:
=x+dx[b[I]];
Y:
=y+dy[b[I]];
Write(‘-(‘,x,’,’,y,’)’);
End;
Writeln
End.
7、[问题描述]
设有1克、2克、5克、10克、20克、50克的砝码各若干枚,问用这些砝码可称出多少不同的重量,设砝码的总重不超过1000克。
prgqrama204();
vard,b;array[1..7]ofinteger;
p:
arrary[0..1000]of0..1;
i,j,w,total:
integer;
begin
fori:
=1to6do
read(d[i]);
readln
d[7]:
=1;
fori:
=1to7do
b[i]:
=0;
fori:
=1to1000do
p[i]:
=0;
whileb[7]=0do
begin
j:
=1;
whileb[j]=d[j]do;
;
fori:
=1toj-1dob[i]:
=0;
;
p[w]:
=1
end;
total:
=0
fori:
=1to1000dototal:
=total+p[i];
writeln('total=',total)
end.
8、[问题描述]
设有1分、2分、5分、1角、5角、1元、2元、5元、10元的钱币各若干张,问用这些钱币能组成多少种不同面值。
设钱币的总数不超过100元,并能求出给出的某个面值,能有多种不同方法产生面值。
例如有1分3张,2分3张,5分1张能组成7分面值的方法有:
3个1分+2个2分,1个1分+3个2分,2个1分+5分,1个2分+1个5分共四种。
programA205
var
d,b:
arrary[1..11]ofinteger;
e:
arrary[1..10]ofinteger;
p:
arrary[0..10000]ofinteger;
i,j,w,total:
integer;
begin
fori:
=1to10do
read(d[i]);
readln;
d[11]:
=1;
fori:
=1to11do
b[i]:
=0
fori:
=1to10000do
p[i]:
=0;
e[1]:
=1;
e[2]:
=2;
e[3]:
=5;
e[4]:
=10;
e[5]:
=20;
e[6]:
=50;
e[7]:
=100;
e[8]:
=200;
e[9]:
=500;
e[10]:
=1000;
whileb[11]=0do
begin
j:
=1
whileb[j]=d[j]doj:
=j+1;
b[j]:
=b[j]+1;
fori:
=1toj-1dob[i]:
=0;
w:
=o;
fori:
=1to10do
w:
=w+b[i]*e[i];
p[w]:
=p[w]+1
end;
total:
=0;
fori:
=1to10000do
ifp[i]>0thentotal:
=total+1;
writeln(‘total=’,total);
write(‘w=’);
readln(w);
writeln(p[w])
end.
9、[问题描述]
四色问题:
如图所示,每个区域代表一个省,区域中的数字代表省的编号,今将每个省涂上红(R),兰(Y),白(W)四种颜色之一,使相邻的省份有不同的颜色。
Programa206;
Varr:
array[1..100,1..100]of0..1;
N,x,y:
integer;
S:
array[1..100]ofinteger;
Proceduremapcolor;
VarI,j,k:
integer;
Begin
S[1]:
=1;
I:
=2;j:
=1;
WhileI<=ndo
While(j<=4)and(I<=n)do
Begin
K:
=1;
While(kj)dok:
=k+1;
Ifk=j+1
Elsebegin
S[I]:
=j;
I:
=I+1;
J:
=1
End;
Ifj>4then
Begin
I:
=I-1;
J:
=s[I]+1
End
End
End;
Begin
Write(‘n=‘);
Readln(n);
Fory:
=1tondo
Begin
Forx:
=1tondo
Read(r[x,y]);
Readln
End;
Mapcolor;
Forx:
=1tondo
Writeln(x,’:
‘,s[x])
End.
10、[问题描述]
无根树的编码:
设有n个结点(编号为0,1,……n-1)的无根树如图1所示。
今给每个结点一个编号,编号取值为0,1,……n-1。
编号给出之后,使相邻结点编号差的绝对值正好构成一个等差数列,如图2所示的结点编号(括号中的数字)。
相邻结点编号差的绝对值正好为1,2,……,8。
Prograama207
Varr:
array[0.99,0..99]of0..1;
S:
array[0.99]ofinteger;
N,I,j,k,p,t;integer;
Functionf:
Boolean;
VarI,j,w:
integer;
T:
array[1..99]ofinteger;
Begin
ForI:
=1ton-1dot[I]:
=0;
ForI:
=0ton-1do
Forj:
=0ton-1do
Ifr[I,j]=1then
Begin
W:
=abs(s[I]-s[j]);
T[w]:
=1
End;
W:
=0;
ForI:
=1ton-1dow:
=w+t[I];
Ifw=n-1thenf:
=trueelsef:
=false
End;
Begin
Write(‘n=‘);
Readln(n);
ForI:
=0ton-1do
Read(r[I,j]);
Readln
End;
ForI:
=0ton-1dos[j]:
=I;
Whilenotfdo
Begin
J:
=n-1;
Whiles[j]
=j-1;
P:
=j;
ForI:
=j+1ton-1do
If(s[I]>s[j-1])and(s[I]
=I;
T:
=s[j-1];
S[j-1]:
=s[p];
S[p]:
=t;
ForI:
=jton-2do
Fork:
=I+1ton-1do
Ifs[I]>s[k]then
Beign
T:
=s[I];
S[I]:
=s[k];
S[k]:
=t
End
End;
ForI:
=0ton-1do
Write(s[I]:
3);
Writeln
End.
11、[问题描述]
设有n物品,每件物品有一个重量和一个价值,分别记为:
w1,w2,……wn—重量
c1,c2,……cn—价值
今有一个背包,其最大载重量为xk,要求从n件物品中任取若干件(可以一件也不取,也可以全取),使得重量之和〈=xk,而价值之和为最大。
由上可知,当xk小于所有的wi时(I=1,2,……n),些时可取物品为0件,当xk>=w1+w2+……wn时,则全取。
Programa208
Varw,c:
array[1..100]ofreal;
B,d:
array[0..100]of0..1;
N:
integer;
Xk:
real;
I,j:
integer;
Cmax,wk,ck:
real:
Begin
Write(‘n=‘);
Readln(n);
ForI:
=1tondoread(w[I],c[I]);
Readln;
Write(‘xk=’);
Readln(xk);
ForI:
=0tondobeginb[I]:
=0;d[I]:
=0end;
Cmax:
=0;
Whileb[0]=0do
Begin
J:
=n;
Whileb[j]=1doj:
=j-1;
B[j]:
=1;
ForI:
=j+1tondob[I]:
=0;
Wk:
=0;
ForI:
=1tondowk:
=wk+b[I]*w[I];
Ck:
=0;
ForI:
=1tondock:
=ck+b[I]*c[I];
If(wk<=xk)and(ck>cmax)then
Begin
Cmax:
=ck;
D:
=b
End
End;
Writeln(‘cmax=‘,cmax:
0:
2);
ForI:
=1tondo
Ifd[I]=1then
Write(I:
3)
End.
12、[问题描述]
设有图所示的一个棋盘,在棋盘上的A点,有一个中国象棋的马,并约定马走的规则:
(1)马走日字
(2)马只能向右走
找出一条从A到B的路径
Programa4;
Var
N,m:
integer;
Begin
Proceduremove(x,y:
byte;varx1,y1:
byte;I:
byte);
Begin
CaseIof
1:
beginx1:
=x-2;y1=y+1;end;
2:
beginx1:
=x-1;y1:
=y+2;end;
3:
beginx1:
=x+1;y1:
=y+2;end;
4:
beginx1:
=x+2;y1:
=y+1;end;
end;
end;
Procedureprint(k:
integer);
Var
X,y,x0,y0:
byte;
Begin
X=1;y=1;
Write(‘(‘,x,’,’,y,’)’);
ForI:
=1tokdo
Begin
Move(x,y,x0,y0,path[I]);
Write(‘—>(‘,x0,’,’,y0,’)’);
X:
=x0;y:
=y0;
End;
Writeln
End;
Proceduresearch(k:
integer;x,y:
byte);
Var
I;integer;
X1,y1:
byte;
Begin
If(x=n)and(y=m)
Then
Begin
Print(k-1);halt;
End;
ForI:
=1to4do
Begin
Move(x,y,x1,y1,I);
If(x1in[1..n])and(y1in[y+1..m])
Then
Begin
Path[k]:
=I;
Search(k+1,x1,y1);
End;
End;
End;
Begin
Readln(n,m)
Search(1,1,1);
End;
13、[问题描述]
计算拆分方案:
任何大于1的自然数n都可以拆分若干个小于n自然数之和。
输入n,计算和输出n的不同拆分方案。
Programw3;
Var
n,i:
integer;
Proceduresum(kx:
inte