- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
回溯法习题汇总1.1马拦过河卒源程序名knight.(pas,c,cpp)可
回溯法习题汇总
1.1 马拦过河卒
源程序名 knight.???(pas, c, cpp)
可执行文件名 knight.exe
输入文件名 knight.in
输出文件名 knight.out 【问题描述】
棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过15的整数),同样马的位置坐标是需要给出的。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
【输入】
一行四个数据,分别表示B点坐标和马的坐标。
【输出】
一个数据,表示所有的路径条数。
【样例】
knight.in knight.out
6 6 3 3 6
【算法分析】
从起点开始往下走(只有两个方向可以走),如果某个方向可以走再继续下一步,直到终点,此时计数。最后输出所有的路径数。这种方法可以找出所有可能走法,如果要输出这些走法的话这种方法最合适了,但是本题只要求输出总的路径的条数,当棋盘比较大时,本程序执行会超时,此时最好能找出相应的递推公式更合适,详见后面的递推章节。
1.2 出栈序列统计 1.3 算24点 1.4 冗余依赖 begin
for i:=1 to 4 do{分别对4个点进行试探}
begin
先记住当前点的位置,已走过的情况和走过的路;
如果第i个点(xl,y1)可以走,则走过去;
如果已达终点,则输出所走的路径并置有路可走的信息,
否则继续从新的点往下查找search(xl,y1,b1,p1);
end;
end;
【思考与提高】
该程序通过引进新的变量和数组来继续新的查找,如果不引进新的变量和数组,那么每一次返回时要将原来的值还原才行,如果那样,程序应如何修改?其实那样更加符合回溯的思想——换条路再试。这类问题也可以归为搜索的问题,如果m和n的值相对比较大,则解可能很多,若题目只要找到一条路就结束程序时,在程序的输出部分后面加上一个halt就行了。
有些情况很明显是无解的,如从起点到终点的矩形中有一行或一列都是为0的,明显道路不通,对于这种情况要很快地“剪掉”多余分枝得出结论,这就是搜索里所说的“剪枝”。从起点开始往下的一层层的结点,看起来如同树枝一样,对于其中的“枯枝”——明显无用的节点可以先行“剪掉”,从而提高搜索速度。
1.6 单向双轨道
1.7 组合的输出 l 2 3 l 2 4 1 2 5 l 3 4 l 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5
【输入】
一行两个自然数n、r(1n21,1=r=n)。
【输出】
所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。
【样例】
compages.in compages.out
5 3 1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
【算法分析】
如果通过循环加递归来实现回溯比较简单,相应程序为:
const max=20;
var a:array[0..max]of integer;
n,r:1..max;
procedure compages(k:integer);{选取第k个元素}
var i,j:integer;
begin
{当前所选元素最小为前一个元素加1,最大为n-(r-k),因为后面还有(r-k)个元素要选取,至少为每次选取留一个}
for i:=a[k-1]+1 to n-(r-k) do begin
a[k]:=i; {选取一个元素}
if k=r then begin
for j:=1 to r do write(a[j]:3);
文档评论(0)