人人终身学习知识网~是各类综合知识资源信息分享,提升综合素质与提高知识技能的终身学习网络平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

信息学竞赛常用算法与策略:回溯 标签:信息学

[复制链接]

优学合肥奥数网讯:信息学竞赛常用算法与策略:回溯

回溯是按照某种条件往前试探搜索,若前进中遭到失败,则回过头来另择通路继续搜索.

3.1 回溯的设计

1.用栈保存好前进中的某些状态.

2.制定好约束条件

例1由键盘上输入任意n个符号;输出它的全排列.

program hh;

const n=4;

var i,k:integer;

x:array[1..n] of integer;

st:string[n];

t:string[n];

procedure input;

var i:integer;

begin

write('Enter string=');readln(st);

t:=st;

end;

function place(k:integer):boolean;

var i:integer;

begin

place:=true;

for i:=1 to k-1 do

if x[i]=x[k] then

begin place:=false; break end ;

end;

procedure print;

var i:integer;

begin

for i:=1 to n do write(t[x[i]]);

writeln;

end;

begin

input;

k:=1;x[k]:=0;

while k>0 do

begin

x[k]:=x[k]+1;

while (x[k]<=n) and (not place(k)) do x[k]:=x[k]+1;

if x[k]>n then k:=k-1

else if k=n then print

else begin k:=k+1;x[k]:=0 end

end ;

end.

例2.n个皇后问题:

program hh;

const n=8;

var i,j,k:integer;

x:array[1..n] of integer;

function place(k:integer):boolean;

var i:integer;

begin

place:=true;

for i:=1 to k-1 do

if (x[i]=x[k]) or (abs(x[i]-x[k])=abs(i-k)) then

place:=false ;

end;

procedure print;

var i:integer;

begin

for i:=1 to n do write(x[i]:4);

writeln;

end;

begin

k:=1;x[k]:=0;

while k>0 do

begin

x[k]:=x[k]+1;

while (x[k]<=n) and (not place(k)) do x[k]:=x[k]+1;

if x[k]>n then k:=k-1

else if k=n then print

else begin k:=k+1;x[k]:=0 end

end ;

end.

3.2 回溯算法的递归实现

由于回溯算法用一栈数组实现的,用到栈一般可用递归实现。

上述例1的递归方法实现如下:

program hh;

const n=4;

var i,k:integer;

x:array[1..n] of integer;

st:string[n];

t:string[n];

procedure input;

var i:integer;

begin

write('Enter string=');readln(st);

t:=st;

end;

function place(k:integer):boolean;

var i:integer;

begin

place:=true;

for i:=1 to k-1 do

if x[i]=x[k] then

begin place:=false; break end ;

end;

procedure print;

var i:integer;

begin

for i:=1 to n do write(t[x[i]]);

writeln;readln;

end;

procedure try(k:integer);

var i :integer;

begin

if k=n+1 then begin print;exit end;

for i:=1 to n do

begin

x[k]:=i;

if place(k) then try(k+1)

end

end;

begin

input;

try(1);

end.

例2:n皇后问题的递归算法如下:

程序1:

program hh;

const n=8;

var i,j,k:integer;

x:array[1..n] of integer;

function place(k:integer):boolean;

var i:integer;

begin

place:=true;

for i:=1 to k-1 do

if (x[i]=x[k]) or (abs(x[i]-x[k])=abs(i-k)) then

place:=false ;

end;

procedure print;

var i:integer;

begin

for i:=1 to n do write(x[i]:4);

writeln;

end;

procedure try(k:integer);

var i:integer;

begin

if k=n+1 then begin print; exit end;

for i:= 1 to n do

begin

x[k]:=i;

if place(k) then try(k+1);

end;

end ;

begin

try(1);

end.

程序2:

说明:当n=8 时有30条对角线分别用了l和r数组控制,

用c数组控制列.当(i,j)点放好皇后后相应的对角线和列都为false.递归程序如下:

program nhh;

const n=8;

var s,i:integer;

a:array[1..n] of byte;

c:array[1..n] of boolean;

l:array[1-n..n-1] of boolean;

r:array[2..2*n] of boolean;

procedure output;

var i:integer;

begin

for i:=1 to n do write(a[i]:4);

inc(s);writeln(' total=',s);

end;

procedure try(i:integer);

var j:integer;

begin

for j:=1 to n do

begin

if c[j] and l[i-j] and r[i+j] then

begin

a[i]:=j;c[j]:=false;l[i-j]:=false; r[i+j]:=false;

if i

c[j]:=true;l[i-j]:=true;r[i+j]:=true;

end;

end;

end;

begin

for i:=1 to n do c[i]:=true;

for i:=1-n to n-1 do l[i]:=true;

for i:=2 to 2*n do r[i]:=true;

s:=0;try(1);

writeln;

end.

练习:

1.找出所有从m个元素中选取n(n<=m)元素的组合。

2.设有A,B,C,D,E 5人从事j1,j2,j3,j4,j5 5项工作每人只能从事一项,它们的

效益表如下:

求最佳安排,使效益最高.

3.N个数中找出M个数(从键盘上输入正整数N,M后再输入N个正数),要求从N个数中

找出若干个数,使它们的和为M,把满足条件的数组找出来,并统计组数.

4.地图着色。如下图12个区域用4种颜色着色要求相邻的区域着不同的颜色

5.将任意一正整数(1

如:4=1+1+1+1

=2+1+1

=2+2

=3+1.

关于合肥市青少年信息学竞赛更多的信息,请关注优学合肥奥数网“青少年信息学竞赛”频道。

信息学竞赛常用算法与策略:递归

信息学竞赛常用算法与策略:算法的概念

青少年信息学竞赛Pascal语言:程序调试(十一)

青少年信息学竞赛Pascal语言:指针(十)

更多精彩内容推荐>>

回复

使用道具 举报

小黑屋/人人终身学习知识网~是各类综合知识资源信息分享,提升综合素质与提高知识技能的终身学习网络平台

Powered by 5wangxiao

© 2007-2021 5wangxiao.Com Inc.

快速回复 返回顶部 返回列表