回溯题解

合集下载

回溯法课程知识点总结

回溯法课程知识点总结

回溯法课程知识点总结在回溯法中,通常使用递归的方式来遍历解空间树,每次遍历到下一层时,都会尝试选择一个决策。

如果选择的决策不满足约束条件,则进行回溯,取消该决策,重新选择其他决策。

当所有的决策都尝试完毕后,就回到上一层继续尝试其他决策,直至搜索到满足约束条件的解,或者搜索完整个解空间树。

回溯法的优点是能够有效地遍历解空间树,找到满足约束条件的解。

它也具有灵活性高、适用范围广等优点。

但同时,回溯法也存在着时间复杂度高、搜索空间大等缺点。

在实际应用中,回溯法通常需要结合具体问题进行适当地优化,以提高搜索效率。

下面我们将介绍回溯法的具体实现和应用。

1. 回溯法的实现回溯法的实现通常由两部分组成:递归函数和决策函数。

递归函数用于遍历解空间树,决策函数用于判断是否满足约束条件和进行决策选择。

下面以求解八皇后问题为例,介绍回溯法的实现。

八皇后问题是一个经典的回溯法应用题目,在一个8×8的棋盘上摆放八个皇后,使得它们互相不攻击。

互相不攻击的条件是:任意两个皇后不在同一行、同一列或同一斜线上。

```pythondef solve_n_queens(n):res = []def backtrack(path):if len(path) == n:res.append(path[:])returnfor i in range(n):if is_valid(path, i):path.append(i)backtrack(path)path.pop()def is_valid(path, col):row = len(path)for i in range(row):if path[i] == col or abs(row - i) == abs(col - path[i]):return Falsereturn Truebacktrack([])return res```在上面的代码中,solve_n_queens函数用于求解八皇后问题,其实现思路如下:首先,定义一个回溯函数backtrack,用于遍历解空间树。

第5章 回溯法

第5章  回溯法
第5章
教学要求

回溯
了解回溯算法的概念与回溯设计要领 掌握应用回溯算法求解桥本分数式、素数环、 数码串珠以及情侣拍照等典型案例
本章重点

理解回溯法 “向前走,碰壁回头”的实现
5.1 回溯概述

1. 回溯的概念
(1) 回溯法(Back track method)有“通用解题法”之美 称,是一种比枚举“聪明”的效率更高的搜索技术。

4. 4皇后问题的回溯举例
如何在4×4的方格棋盘上放置4个皇后,使它们互不攻击:

4皇后问题回溯描述
i=1;a[i]=1; while


(1) { g=1;for(k=i-1;k>=1;k--) if(a[i]=a[k] || abs(a[i]-a[k])=i-k) g=0; // 检测约束条件,不满足则返回 if(g && i==4) printf(a[1:4]); // 输出一个解 if(i<4 && g) {i++;a[i]=1;continue;} while(a[i]==4 && i>1) i--; // 向前回溯 if(a[i]==4 && i==1) break; //退出循环结束探索 else a[i]=a[i]+1; }
(2) 回溯描述 对于一般含参量m,n的搜索问题,输入正整数n,m,(n≥m) i=1;a[i]=<元素初值>; while (1) {for(g=1,k=i-1;k>=1;k--) if( <约束条件1> ) g=0; // 检测约束条件,不满足则返回 if(g && <约束条件2>) printf(a[1:m]); // 输出解 if(i<n && g) {i++;a[i]=<取值点>;continue;} while(a[i]=<回溯点> && i>1) i--; // 向前回溯 if(a[i]==n && i==1) break; // 退出循环,结束 else a[i]=a[i]+1; }

算法分析与设计

算法分析与设计
他把1,2,3,...16 这16个数字填写在4 x 4的方格中。 16 ? ? 13 ? ? 11 ? 9??* ? 15 ? 1
表中有些数字已经显露出来,还有些用?和*代替。 请你计算出? 和 * 所代表的数字。并把 * 所代表的数字作为本题答 案提交。
素数环问题
素数环是一个计算机程序问题,指的是将从1到n这n个整数围成一 个圆环,若其中任意2个相邻的数字相加,结果均为素数,那么这个环 就成为素数环。现在要求输入一个n,求n个数围成一圈有多少种素数 环,规定第一个数字是1。 143256 165234
例如当n=5,m=4时,面值为1,3,11,15,32的5种邮票可以贴 出邮资的最大连续区间是1到70。
➢ 通用的解题法 ➢ 核心在于构造解空间树:
➢ 子集树 ➢ 排列树 ➢ 回溯法是优化的暴力搜索: ➢ 不满足限制条件; ➢ 当前解与最优解进行预计算; ➢ 学习回溯法:心中有树
回溯法
总结
➢ 动态规划适合两个连续步骤之间有联系的问题; ➢ 回溯法几乎适用于所有的问题,但问题之间最好有明确的层次。
总结
➢ 构造心中的解空间树是关键; ➢ 回溯法与函数的局部变量; ➢ 访问解空间树的优化处理;
迷宫问题中的回溯法
➢ 四邻域 ➢ 八邻域
图论问题
无向图: ➢ 连通 ➢ 不连通
有向图: ➢ 弱连通 ➢ 单向连通 ➢ 强连通
最大团问题
连通子图(分支)
最大团问题
给定无向图G=(V,E),如果UV,且对任意的u,vU, 都有(u,v)E,则称U是G的完全子图。G的完全子图U是G 的一个团当且仅当U不包含在G的更大的完全子图中。G中 的最大团是指G中所含顶点数最多的团。
yes no yes
➢ 通用的解题法 ➢ 核心在于构造解空间树:

回溯法 符号三角形

回溯法 符号三角形

回溯法符号三角形1. 引言回溯法是一种常见的解决问题的算法,它通过穷举所有可能的解来找到问题的最优解。

符号三角形是一种由符号组成的图形,通常用于逻辑推理和数学计算。

本文将介绍回溯法在解决符号三角形问题中的应用。

2. 符号三角形问题符号三角形是由一系列符号组成的等边三角形,每个位置可以填入不同的符号。

例如,下面是一个由A、B、C、D四个符号组成的符号三角形:AB CD A B给定一个符号三角形,我们需要找到一种填充方式,使得每个位置上填入的符号满足特定条件。

这个条件可以是相邻位置上填入的符号不能相同,或者每行每列上填入的符号之和等于某个特定值。

3. 回溯法解决符号三角形问题回溯法是一种递归搜索算法,它通过尝试所有可能的解来找到最优解。

在解决符号三角形问题中,我们可以采用回溯法来穷举所有可能的填充方式,并判断是否满足条件。

3.1 算法思路回溯法解决符号三角形问题的基本思路如下:1.遍历符号三角形的每个位置,从第一行第一个位置开始。

2.在当前位置尝试填入一个符号。

3.判断当前填入的符号是否满足条件,如果满足则继续下一步,否则回溯到上一步。

4.如果已经遍历完所有位置,并且所有填入的符号都满足条件,则找到了一个解。

输出这个解,或者记录下来。

5.继续尝试下一个可能的填充方式,重复步骤2-4,直到遍历完所有可能的填充方式。

3.2 代码实现下面是使用Python语言实现回溯法解决符号三角形问题的代码:def backtrack(triangle, row, col, symbols):if row == len(triangle):# 找到了一个解print_solution(triangle)returnfor symbol in symbols:triangle[row][col] = symbolif is_valid(triangle, row, col):# 符号满足条件,继续下一步next_row, next_col = get_next_position(row, col) backtrack(triangle, next_row, next_col, symbols)triangle[row][col] = Nonedef print_solution(triangle):for row in triangle:for symbol in row:print(symbol or ' ', end=' ')print()def is_valid(triangle, row, col):# 判断当前填入的符号是否满足条件if row > 0 and triangle[row][col] == triangle[row-1][col]: return Falseif col > 0 and triangle[row][col] == triangle[row][col-1]: return Falsereturn Truedef get_next_position(row, col):# 获取下一个位置if col < row:return row, col+1else:return row+1, 0def solve_triangle(triangle, symbols):backtrack(triangle, 0, 0, symbols)# 测试代码triangle = [[None]*i for i in range(1, 5)]symbols = ['A', 'B', 'C', 'D']solve_triangle(triangle, symbols)4. 总结回溯法是一种通过穷举所有可能的解来找到问题最优解的算法。

回溯法的基本介绍以及原理

回溯法的基本介绍以及原理

回溯法的基本介绍以及原理
回溯法是一种通过逐步试探、回溯到上一步来寻找问题解的方法。

它适用于在一个问题的解空间中搜索所有可能的解,通过深度优先的方式进行搜索。

回溯法的基本原理是:从问题的初始状态开始,不断地进行选择,当发现选择导致了无效的解或者无法继续选择时,就回溯到上一步重新进行选择。

在回溯的过程中,保存了每一步的选择,这样可以在找到一个解或者搜索完整个解空间后,利用已经保存的选择恢复出解。

具体来说,回溯法一般包含以下步骤:
1. 定义问题的解空间:也就是问题的所有可能的解组成的空间。

2. 制定问题的解空间的搜索规则:决定了在解空间中搜索的顺序和方式。

3. 利用深度优先的方式进行搜索:从问题的初始状态开始,逐步进行选择,如果选择导致了无效的解或者无法继续选择,则回溯到上一步。

4. 终止条件:当搜索完整个解空间或者找到一个解时,终止搜索。

回溯法的时间复杂度一般很高,因为它需要搜索整个解空间。

但是,通过合理的剪枝策略,可以减少搜索的路径,降低时间
复杂度。

回溯法常常应用于解决组合问题、排列问题、子集问题等涉及组合选择的问题,也可以用于解决图的遍历问题等其他类型的问题。

回溯法详解

回溯法详解

回溯法详解
回溯法是一种常用的算法思想,通常用于解决一些组合问题,如排列、组合、子集等。

回溯法的基本思想是从一组可能的解中逐一尝试,如果发现当前尝试的解不符合要求,则回溯到上一步继续尝试其他解。

回溯法可以看作是一种深度优先搜索算法,它的搜索过程类似于一棵树的遍历。

在搜索过程中,从根节点开始,逐层向下搜索,直到找到符合条件的解或者搜索完所有的可能情况。

回溯法的实现通常采用递归的方式,具体步骤如下:
1. 定义一个解空间,即所有可能的解的集合。

2. 逐步扩展解空间,直到找到符合条件的解或者搜索完所有可
能的情况。

3. 在扩展解空间的过程中,对于每个扩展的状态,检查它是否
符合要求,如果符合要求,则继续扩展;否则回溯到上一步。

回溯法的时间复杂度通常很高,因为它需要搜索所有的可能情况。

但是在实际应用中,回溯法的效率往往比暴力枚举要高,因为它能够利用一些剪枝策略,避免搜索无用的状态。

例如,在求解八皇后问题时,回溯法可以通过剪枝策略,避免搜索一些不可能的状态,从而大大缩短搜索时间。

回溯法也是一种非常灵活的算法思想,可以应用于各种问题的求解。

在实际应用中,需要根据具体问题的特点,设计合适的解空间和剪枝策略,以提高算法效率。

回溯法旅行商问题(TSP问题)

回溯法旅⾏商问题(TSP问题)学习链接:、今天早上做了⽆数个梦,然后被紧紧地吸附在床上。

挣扎⼀番后爬起来,已经是9点了。

然后我开始研究旅⾏商问题。

在⼀个⽆向图中找到⼀个可以遍历所有节点的⼀个最短回路。

理论上说可以⽤全排列列出所有解的下标,然后⼀个⼀个试,时间复杂度o(n!)。

但是可以⽤回溯法,⽤【约束函数】(constraint)判断当前路径是否连通,⽤【界限函数】(bound)判断当前路径是否⽐已经求得的最短路径⼩。

这两个判断任意⼀个不符,则做“剪枝操作”(不再对后续节点进⾏遍历)。

可以看出回溯法⽐穷举要⾼明的多。

这个回溯法和⼋皇后问题也有⼀些区别。

TSP问题需要构造⼀棵排列树:根节点为{0}第⼀层{0,1}第⼆层{0,1,2},{0,2,1}第三层{0,1,2,3},{0,1,3,2},{0,2,1,3},{0,2,3,1},{0,3,1,2},{0,3,2,1}……并且回溯法要求对图进⾏DFS操作,即深度优先搜索。

因为需要⾸先⾸次找到最深处的节点,才能设置当前最优解,好让后续问题能有参考。

Java代码:1public class Main {23public static void main(String[] args) {4int[][] adjMatrix={5 {0,20,6,4},6 {20,0,5,10},7 {6,5,0,15},8 {4,10,15,0},9 };10 TSP problem=new TSP(adjMatrix);111213 }14 }1516class TSP{17int vexnum=0;//顶点数⽬18int adjMatrix[][];19 TSP(int[][] adjMat){20 adjMatrix=adjMat;21 vexnum=adjMatrix.length;22int init[]={0};23 Backtrack(1,init);24int a;25 a=0;26 }27int bestCost=0;28int[] bestX;//最优解向量29boolean isTraverseDeep=false;30//回溯法递归31//初始x:[0]32void Backtrack(int t,int[] x){//对顶点t进⾏操作,⽗结点的解向量是x,33if(t>=vexnum){//解向量的第⼀个元素应该是初始顶点,如0,最后⼀个元素也是034 x[t]=0;//最后⼀个节点赋值:0。

回溯法原则

回溯法原则
回溯法原则是一种问题求解的方法,也称为回溯搜索或试探法。

它通常用于解决组合优化、排列组合、装箱、密码破解等问题。

回溯法的基本思想是从问题的开始状态开始,逐步尝试各种可能的选择,并进行系统性地搜索。

在搜索的过程中,如果发现当前的选择方案不能得到有效的解决方案,就回溯到上一步,并尝试其他的选择,直到找到符合问题要求的解决方案,或者全部搜索完毕。

回溯法的主要步骤如下:
1. 定义问题的解空间:确定问题的解空间是指问题的解可取的范围或者搜索的空间限制。

2. 选择搜索的方向:根据问题的特点和要求,确定搜索的方向和策略。

3. 进行搜索:采用递归方式或者迭代方式,按照确定的搜索方向,逐步尝试不同的选择,并对每一次选择进行验证和判断。

4. 回溯:如果当前的选择不能得到有效的解决方案,则回溯到上一步,重新选择其他的可能,并再次进行验证和判断。

5. 终止条件:在搜索的过程中,根据问题的要求设置合适的终止条件,当满足终止条件时,停止搜索,输出结果。

回溯法是一种穷举搜索的方法,时间复杂度较高,需要进行大量的尝试和验证。

因此,在使用回溯法解决问题时,需要注意问题的规模和复杂度,以避免搜索空间过大导致的效率问题。

同时,还可以通过剪枝等优化策略来提高搜索效率。

回溯法和分支限界法解决0-1背包题要点教学内容

回溯法和分支限界法解决0-1背包题要点0-1背包问题计科1班朱润华 2012040732方法1:回溯法一、回溯法描述:用回溯法解问题时,应明确定义问题的解空间。

问题的解空间至少包含问题的一个(最优)解。

对于0-1背包问题,解空间由长度为n的0-1向量组成。

该解空间包含对变量的所有0-1赋值。

例如n=3时,解空间为:{(0,0,0),(0,1,0),(0,0,1),(1,0,0),(0,1,1),(1,0,1),(1,1,0),(1,1,1)}然后可将解空间组织成树或图的形式,0-1背包则可用完全二叉树表示其解空间给定n种物品和一背包。

物品i的重量是wi,其价值为vi,背包的容量为C。

问:应如何选择装入背包的物品,使得装入背包中物品的总价值最大?形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找一n元向量(x1,x2,…,xn,), xi∈{0,1}, ? ∑ wi xi≤c,且∑ vi xi达最大.即一个特殊的整数规划问题。

二、回溯法步骤思想描述:0-1背包问题是子集选取问题。

0-1 背包问题的解空间可以用子集树表示。

在搜索解空间树时,只要其左儿子节点是一个可行节点,搜索就进入左子树。

当右子树中有可能含有最优解时,才进入右子树搜索。

否则,将右子树剪去。

设r是当前剩余物品价值总和,cp是当前价值;bestp是当前最优价值。

当cp+r<=bestp时,可剪去右子树。

计算右子树上界的更好的方法是将剩余物品依次按其单位价值排序,然后依次装入物品,直至装不下时,再装入物品一部分而装满背包。

例如:对于0-1背包问题的一个实例,n=4,c=7,p=[9,10,7,4],w=[3,5,2,1]。

这4个物品的单位重量价值分别为[3,2,3,5,4]。

以物品单位重量价值的递减序装入物品。

先装入物品4,然后装入物品3和1.装入这3个物品后,剩余的背包容量为1,只能装0.2的物品2。

0-1背包问题(回溯法)

0-1背包问题(回溯法)实验报告姓名:学号:指导老师:一.算法设计名称:0-1背包问题(回溯法)二.实验内容问题描述:给定n 种物品和一背包。

物品i 的重量是w i ,其价值为v i ,背包的容量为C 。

问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?在选择装入背包的物品时,对每种物品i 只有两种选择,即装入背包或不装入背包。

不能将物品装入背包多次,也不能只装入部分的物品。

三.实验目的1.运用回溯思想,设计解决上述问题的算法,找出最大背包价值的装法。

2.掌握回溯法的应用四.算法设计:问题求解思路1.由0-1背包问题的最优子结构性质,建立计算m[i][j]的递归式如下:i i i w j w j j i m i v w j i m j i m j i m <≤≥⎩⎨⎧-+---=0],1[]}[],1[],,1[max{),(2.查找装入背包物品的回溯函数:从0-1二叉树的根开始搜索:若是叶子节点,则判断此时的价值是否比当前最优的价值大,否则将之替换,并获得最优解向量且返回;若不是叶子节点,则向左右子树搜索,先改变当前的数据状态,递归的调用自己,然后恢复数据状态表示回溯。

3.边界函数bound主要是当还未搜索到叶子节点时,提前判断其子树是否存可能存在更优的解空间,否则进行回溯,即裁剪掉子树的解空间。

关键数据结构及函数模块:(Backtrack.h )#ifndef __BACKTRACK_H__#define __BACKTRACK_H__class BP_01_P{public:∑=ni i i x v 1max ⎪⎩⎪⎨⎧≤≤∈≤∑=n i x C x w i n i i i 1},1,0{1BP_01_P(int w,int n):m_Sum_weitht(0),m_Number(0) {m_Sum_weitht=w;m_Number=n;bestHav=0;bestVal=0;curVal=0;curHav=0;m_hav=new int[n];m_val=new int[n];temop=new int[n];option=new int[n];}~BP_01_P(){delete []m_hav;delete []m_val;delete []temop;delete []option;}void traceBack(int n);int bound(int n);void printBestSoulation();int *m_hav;//每个物品的重量int *m_val;//每个物品的价值int *temop;//01临时解int *option;//01最终解int bestHav;//最优价值时的最大重量int bestVal;//最优的价值int curVal;//当前的价值int curHav;//当前的重量private:int m_Sum_weitht;//背包的总容量int m_Number;//物品的种类};#endif __BACKTRACK_H__五:主要的算法代码实现:(Backtrack.cpp)边界函数:bound( )int BP_01_P::bound(int n){int hav_left=m_Sum_weitht-curHav;int bo=curVal;while(n<m_Number && m_hav[n]<=hav_left){hav_left-=m_hav[n];bo+=m_val[n];n++;}if(n<m_Number){bo+=m_val[n]*hav_left/m_hav[n];//bo+=hav_left;}return bo;}回溯递归函数:traceBack( )void BP_01_P::traceBack(int n){if(n>=m_Number){if(curVal>=bestVal){bestVal=curVal;for(int i=0;i<n;i++){option[i]=temop[i];}return ;}}if(curHav+m_hav[n]<=m_Sum_weitht)//向左子树搜索 {curHav=curHav+m_hav[n];curVal=curVal+m_val[n];temop[n]=1;//标记要选择这个物品traceBack(n+1);curHav=curHav-m_hav[n];curVal=curVal-m_val[n];}if(bound(n+1)>bestVal)//向右子树搜索{temop[n]=0;//标记要丢弃这个物品traceBack(n+1);}}主控函数:(main.cpp)#include <iostream>#include "Backtrack.h"using namespace std;int main(){int number,weigth;cout<<"包的总容量:";cin>>weigth;cout<<"物品的种类:";cin>>number;BP_01_P *ptr=new BP_01_P(weigth,number);cout<<"各种物品的重量:"<<endl;for(int i=0;i<number;i++)cin>>ptr->m_hav[i];cout<<"各种物品的价值:"<<endl;for(i=0;i<number;i++)cin>>ptr->m_val[i];ptr->traceBack(0);ptr->printBestSoulation();cout<<"总重量:"<<ptr->bestHav<<"\t总价值:"<<ptr->bestVal<<endl;return 0;}六:算法分析采用回溯法解决0-1背包问题,明显比动态规划法更优良。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

CS1201:闪避湖泊
(来源:POJ 3620,ACM/ICPC程序设计与分析(C++实现) P259)
问题描述:
农夫约翰的农场在最近的一场暴风雨中被水淹没。但保险公司仅根据他得农场中最大的
“湖泊”的大小赔偿一个数额。
农场可表示为N行M列的长方形网格,(1≤N≤100,1≤M≤100)。网格中的每个单元或是
干的或是被淹没的,且恰有K个单元被水淹没,(1≤K≤N*M)。正如人们所希望的,湖泊是
一个中间单元,它与其他的单元共享一条长边(不是角落)。任何与中间单元共享一条长边
或者与连通单元共享一条长边的单元式一个连通单元,是湖泊的一部分。
输入:
有多组数据。每组的第1行有3个整数N,M和K。第2行到第K+1行,是整数R和
C,表示被淹没的位置。
输出:
对每组测试数据,输出有最大湖泊的单元的数目。
样例输入1:
3 4 5
3 2
2 2
3 1
2 3
1 1

样例输出1:
4

样例输入2:
3 5 5
3 2
2 3
3 2
2 4
1 2

样例输出2:
2

样例输入3:
2 4 3
2 2
1 3
4 2
样例输出3:
1

解题分析:
如果每个方格与其四连通的其中一个方格连通则构成一个湖泊,该湖泊所包含的方格数
就是该湖泊的大小,现在要求构成的湖泊中最大的那个湖泊所包含的方格数.
这里用flag[i][j]来表示坐标为(i,j)的农田是干旱还是潮湿,如果潮湿则
flag[i][j]=true,否则为false,根据输入的潮湿的农田的坐标信息将相应的数组元素置为true,然
后运用DFS来求解与该潮湿的农田相连的农田数.。
参考程序:

CS1203:骑士移动(Knight Moves)
(来源:POJ 2243,ZOJ 1091,ACM国际大学生程序设计竞赛题解(2) P126)
问题描述:
你的一个朋友正在研究骑士旅行问题(TKP)。在一个有n个放个的棋盘上,你得找到一
条最短的封闭骑士旅行的路径,使能够遍历每个方格一次。他认为问题的最困难部分在于,
对两个给定的方格,确定骑士移动所需的最小步数。你曾经解决过这类问题,找到这个路径
应该不困难。
当然,你知道反之亦然,所以你帮助他编写一个程序,解决这个“困难的”部分。
你的任务是:输入有两个方格a和b,确定骑士在最短路径上从a到b移动的次数。

输入:
输入包含一组或多组测试例。每个测试例一行,是两个方格,用空格隔开。棋盘上的一
个方格用一个字符串表示,字母(a-h)表示列,数字(1-8)表示行。
输出:
对每个测试例,输出一行:“To get from xx to yy takes n knight moves.”。
样例输入:
e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1

a b c d e f g h
1
2
3
4
5
6
7
8
b1 c3
f6 f6
样例输出:
To get from e2 to e4 takes 2 knight moves.
To get from a1 to b2 takes 4 knight moves.
To get from b2 to c3 takes 2 knight moves.
To get from a1 to h8 takes 6 knight moves.
To get from a1 to h7 takes 5 knight moves.
To get from h8 to a1 takes 6 knight moves.
To get from b1 to c3 takes 1 knight moves.
To get from f6 to f6 takes 0 knight moves.
解题分析:
解决本问题最容易的算法是深度优先搜索,从起点向8个方向递归,计算从该起点到棋
盘上所有位置的最短路径。这个算法最致命的缺点是速度慢,因为计算的工作量太大。
接着就是广度优先搜索算法。该算法也是从起点向8个方向搜索,但不是递归的方式,
而是建立一个队列,将待搜索的结点放到队列里面,已经搜索的结点从队列里面删除,由于
没有重复搜索,效率自然就高很多了。
(1) 骑士走一步可以到哪些位置
由于棋盘是8*8的,在任意一个方格,骑士都可以走到棋盘上的任意其他方格,这样就
有64种可能性;因为有64格,所以要保存任意两格之间的最短路径的步数,需要64*64
的数组;
Int knight[64][64]
现在就需要建立64*64的矩阵数组与棋盘之间的对应关系。设矩阵数组的单元(i,j)
(0≤i,j≤63),对应棋盘上的骑士从方格坐标为a(i/8,i%8)跳到方格坐标b(j/8,j%8),
如果只需要走一步时为1,否则为∞(取10就可以了);方格自身为0。
设(x,y)为方格a和b之间的坐标差值,其计算公式是:
X = i/8 – j/8;
Y = i%8 – j%8;
明显看到,当x方向变化为1时,y方向变化为2;或者x方向变化为2时,y方向变
化为1。因此就有:
If(x==1 && y==2 || y==1)
K[i][j] = k[j][i] = 1 ;
(2) 计算其他的单元格,即棋盘格子之间的最短路径所需的 步数大于1
展判断是否存在可以消去的宝石。

相关文档
最新文档