国际大学生程序设计竞赛试题与算法分析(二) 回溯算法

  • 格式:pdf
  • 大小:269.76 KB
  • 文档页数:4

信意章赛

令毋次豢绪常寻

分潇寥

试题与算法分析二回溯

耳法

郭篙山吴汉荣中山大学信息科技学院计算机科学系广州我们在日常生活中经常会遇到一些要求最优解的问题比如说从一个城市到另一个城市怎么走才最快怎么走才最省钱但是在处理一些最优解的问题方面没有任何的理论也无法采用精确的数学公式来帮助我们找到最优解我们只能求助于穷举搜索方法在这里我们介绍一种系统化的穷举搜索技术称为回溯技术所谓的回溯技术就是像人走迷宫一样先选择一个前进方向尝试一步步往前试探在遇到死胡同不能再往前的时候就回退到上一个分叉点选另一个方向尝试而在前进和回撤的路上都设置一些标记以便能正确返回直到达到目标或者所有的可行方案都已经尝试完为止在通常的情况下我们使用递归方式来实现回溯技术也就是在每一个分叉点进行递归尝试在回溯时通常采用栈来记录回溯过程使用栈可使穷举过程能回溯到所要位置并继续在指定层次上往下穷举所有可能的解回溯算法可以用伪码描述如下当前状态当前状态等于目标状态对所有可能的新状态新状态回溯算法是一种十分常用的算法象一些经典问题如八皇后问题骑士周游问题地图着色问题都可以采用回溯算法来解本期将刊登题历年的国际决赛

和区域赛试题供读者分析和学习每道题都先给

出题目然后是算法分析由于篇幅所限我们

给出主要的解题思路和算法分析具体的程序实现留给读者自行完成

第一题骨牌矩阵问题描述

多米诺骨牌是一个小正方形方块每个骨牌都标有一个数字一现在有组骨牌每组两

个各组编号为一每组编号对应的两个骨牌数

值如下

骨牌组组骨牌牌骨牌组骨牌牌骨牌组骨牌骨牌组骨牌编号编号编号编号

】现将这组骨牌排成一个矩阵此时只能看到每个骨牌上的数字一而不能知道每组

的组号如图所示请编程将每组骨牌分辨出来见图图中数字为对应图每组骨牌的编号骨牌摆放可旋转例如第组骨牌经旋转可得以

种放法万了

第届亚洲台匕赛区中山大学队教

第届亚洲台能赛区中山大学队队长

晦卫卫

翻钧仆伪“仲”曾并翎饥︵匕心公未”从杏少﹄湘用︾骨牌矩阵骨牌组编号矩

图图

如场比代曰曰什州替异知饥︵匕心兮术”片未少毛如剐︶输入格

从键盘输人一个文本文件的文件名该文件包含了一个行列的骨牌矩阵每行有个一的整数每个整数之间用空格分开每行的行首

行末无多余空格榆出格式

答案输出到一个文本文件中文件名由键盘输人若问题无解则输出忆

若问题有解则将所有可能的解输出每个解之间用一个空行分开最后输出解的总数数字间用空格分开算法分析

这题的算法比较简单只需使用标准的回溯算

法而且由于本题的规模比较小不需要对算法进行优化既可满足时间上的要求

在骨牌矩阵中每组骨牌既可以横放也可以竖放我们可以按从左到右从上到下的顺序对骨牌矩阵中的每个位置进行回溯判断相应的骨牌组应该是横放还是竖放最终目标就是要求二十八组骨牌组都能够不重复地排成一个的矩阵而且每个骨牌上的数字和输人的骨牌矩阵一一对应还要求每组骨牌不互相重叠例程中的过程就是用于回溯的递归过程它先查找下一个还没放置骨牌的位置较如已经超过矩阵的范围而且所有的骨牌组已经放置好则表示已经找到一个解将它输出否则按四

种方式尝试放置个骨牌组假如成功则尝试放置

下一个骨牌组假如不成功就回溯

核心算法是递归放置一个骨牌组

信息穿赛

查找下一个还没放置骨牌的位置

,力

若没有则表示已经找到一个解输出返

把在,处的骨牌作为当前骨牌组的一个骨牌把在川处的骨牌作为当前骨牌组的另一个骨牌判断当前骨牌组是否未被使用如果未被使用则递归放置下一个骨牌组把在,处的骨牌作为当前骨牌组的另一个骨牌

判断当前骨牌组是否未被使用如果未被使用则递归放置下一个骨牌组

两种尝试都失败进行回溯

第二题求马的不同走法总数问题描述

在一个的棋盘上马的起始位置坐标纵横位置由键盘输人求马能返回初始位置的所有不同走法的总数马走过的位置不能重复马走旧”字算法分析由于棋盘的大小只有所以只需使用回溯算法搜索马能返回初始位置的所有不同走法效率基本上能达到要求

递归的回溯算法可描述为

是当前位置

马从当前位置出发走一步到位置的每一种走法在棋盘内位置没有走过出发点不同走法总数加

标记已经走过了

取消位置‘的标记

下面讨论算法的具体实现棋盘用坐标表示点表示棋盘上任一个点的范围是‘‘‘‘

从,出发下一步最多有个位置记为……若用表示这个方向则

,

…即马从点出发首先沿的方向行进当

在此方向走完所有的不同走法后就进行回溯改变二方向继续行进

……

。。。乃信窟章赛

各点坐标的计算设点坐标为,则能到达点的坐标分别为一一…

一,一一一为简化坐标的计算引人增

量数组【二一一一一一一一一则按方向能到达点的坐标是

霎入才、、、么夕

产门卜、

夕侧

图马的八种不同走法第三题求不连续重复字符序列问题描述

由大写字母中前个字母‘‘组成字符序列所谓不连续重复字符序列是指字符序列中无连续重复的子串例如以下为有连续重复字串的字符序列

又如以下为没有连续重复字串的字符序列

输入和输出请编写程序读人整数和其中‘‘‘输出第个由前个字母组成的不连

续重复字符序列以及这个序列的长度显然第

个不连续重复字符序列为假定由给出的和

中至少存在个不连续重复序列例如当时前个不连续重复序列为

由于所输出序列可能很长因此输出时以每

个字母为组每组用个空格分开每行个字

符输人以两个时用空格分开结束输人样例

输出样例

算法分析由于只要求最大为所以只需使用回溯

算法搜索生成前个不连续重复字符序列并输出第个不连续重复字符序列即可测试时保证不会超时本题的关键在于判断字符序列有无连续重复字串由于我们是一面搜索一面判断的因此当需要判断一个长度为的字符序列有无连续重复字

串时可以确保前一个字符的序列没有连续重复字串只需检查包含第个字符的字串即可因

为如果这个字符序列含有连续重复字串则必定是

由第个字符造成的判断字符序列有无连续重复字串的函数可描述为

检查长度为的字串一一返回有连续

重复字串

返回没有连续重复字串

需要注意的一点是本题最好使用非递归的搜索算法否则容易造成堆栈溢出可以考虑的优化措施有

为了提高信息的利用率对每个字符序列若没有搜索过可搜索至生成前个不连续重

’。。乃

翻场少找曰什州枯豆︸翎饥︵匕心琶未“八上下七湘用︶信息竟赛

复字符序列并用一个字符串数组记录搜索过程然后从中还原出第个字符序列输出若已经搜索

过直接从中还原出第个字符序列并输出当‘时所产生的前个序列是相同的所以可以直接调用的结果求不连续重复字符序列可描述为

初始化

读人新的

输人合

协声迁的字申还未产生产生的字串

还原出第个序列并输出

二二

把新的序列添加人记录字

串田

已经产生了个字符序列停止搜索

二二,的前一个字符初始化下一层的搜索

一回退一层

把添加人记录字串田

还原的过程可描述为

记录搜索过程和还原出第个字串的实现方法有很多这里对我使用的方法做简单说明非递归的搜索过程可描述为

当前搜索的深度二的前一个字符【当前生成的字符序列

连还未生成个字符序列

二‘前个字母

没有连续重复字串

”让,

删除的最后一个字符

二口,

中存放的是还原出来的字串例如二时搜索结束后记录以下字符串一

一一”表示往回退一位

此字串可表示二时的个序列

然后还原出第个序列并输出收稿日期一一

北女女女北流流女女流女女流女女流女流女女北北女女女女北女流流女女交流流北女女北北流女北北

上接第

翻坏饰样践曰仲们曹开知仇︵匕心分未

”从山少七湘用︶

数据库包含了主数据库以及帐号权限统计汇总等辅助数据库系统管理模块的功能包含系统初始化原始数

据的录人和修改数据定期备份定期统计收费额并自动划款发送电子邮件等子功能安全维护模

块有帐号管理权限管理操作跟踪用日志记录

等功能实现用户安全性数据安全性操作安全性的全面管理这种系统结构模块化程度高可按资金投人情

况技术水平分步实现较为切实可行小结

综上所述笔者认为远传水表的选用与安装并不复杂工程造价也不高而它可多路集中显示大大减少了抄表的工作量也避免了对住户的

扰尤其适用于多层和高层住宅的能源计量管理采用这种科学化的管理方式将会产生相当可观的经济效益和良好的社会效益对我国现行的城市公用事业管理模式的改变起到极大的推动作用收稿日期

一一