马的哈密顿周游(分治)
- 需求分析
0.问题描述
8x8 的国际象棋棋盘上的一只马,恰好走过除起点外的其他63个位置各一次,最后回到起点。这条路线称为马的一条Hamiton周游路线。对于给定的mxn的国际象棋棋盘, m和n均为大于5的偶数,且|m - n|≤2,试设计一个分治算法找出马的一条Hamilton周游路线。
算法设计:对于给定的偶数m, n≥6,且m n1≤2,计算mxn的国际象棋棋盘上马的一条Hamilton周游路线。
1.问题分析
马在棋盘上走日字,从(0,0)开始找一条马的哈密顿回路,就是让马按照日字不重复地走完棋盘上的每一个方格,最后只要判断马到达(1,2)或者(2,1),就知道是不是一条回路。
2.输入数据
输入棋盘的行数和列数
3.输出数据
输出第1种表达方式按照马步的次序给出马的Hamilton周游路线。马的每一步用所在的方格坐标(x, y)来表示。x表示行坐标,编号为0, .,. m-l;y表示列坐标,编号为0,1,*,n-1。
起始方格为(0, 0)。
第2种表达方式在棋盘的方格中标明马到达该方格的步数。(0, 0)方格为起跳步,并标
明为第1步。
4.测试样例设计
6,6
8,12
30,32
100,102
- 算法设计与分析
1.算法的基本思想
①分治的思想。一个棋盘的哈密顿回路可以分解为四个子棋盘的哈密顿回路问题。
分别求出四个子棋盘的哈密顿回路,然后将子问题的解进行合并。
②如何进行合并?
选择结构化的基本子棋盘的解数据。
③最小子问题的解如何得到?
规模达到一定小的子问题的我们可以从文件输入。这里给出了6x6 ,6x8 ,8x6 ,8x8,8x10,10x8,10x10,10x12,12x10规模的子问题的解。
2.输入和输出的格式
从文件input.txt中输入棋盘的行数和列数。
3.算法的具体步骤
先考虑几个问题:
①如何存储棋盘的数据?
- 知道第一步肯定是在(0,0)如果每一步知道下一步的坐标,就可以知道路线。
- 在合并的时候,还需要知道某步的上一步的坐标。
- 用棋盘方格的编号来代表坐标减小维度(i,j) -> x*i+j,用二维数组储存棋盘。
- 每个方格处,储存到达这个方格的上一步的方格编号,和前往的下一步的放格编号。
②得到数据后如何输出?
- 题目按顺序输出每一步到达的方格编号+输出每一个方格是第几步到达
- 方式1:从(0,0),根据二维数组中表示下一步方格编号的参数,沿着路线输出 即可。
方式2:在输出第k步的方格坐标(i,j)时,可以同时存储(i,j)处的步数k
①输入棋盘的行数和列数,输入最小子问题的解。
②判断输入的规格是否符合要求。
③判断规格是否在给出的子问题中,如果在,直接输出。
④将棋盘进行划分,如果不能四等分,m,n=4k+2划分为2k和2k+2的两部分,保证产生行数和列数为偶数的棋盘。
⑤合并子问题的解,得到原问题的解。
⑥输出解。
4.算法的时空分析
①时间性能:T(n)=4T(n/2)+O(1)
k=4,m=2,d=0
m^d<k
T(n)=O(n^2)
②空间性能:O(n)存储棋盘