• 数据结构-马走日的解法


    假设国际象棋棋盘有5*5共25个格子。设计一个程序,使棋子从初始位置(如图)开始跳马,需要将棋盘的格子全部都走一遍,每个格子只允许走一次。

    问:总共有多少解。(提示:回溯法)

    P.S国际象棋的棋子是在格子中间的。国际象棋中的“马走日”,如第一步为[1,1],第二步为[2,8]或[2,12],第三步可以是[3,5]或[3,21]等,以此类推。

    #include <iostream>
    using namespace std;
    
    const int m = 5, n = 5;
    int countN = 0;
    int trace[m][n] = { 0 };
    int changedir[][2] = { {1,2},{2,1},{1,-2},{2,-1},{-1,2},{-2,1},{-1,-2},{-2,-1} };
    
    void printT()
    {
    	for (int i = 0; i < m; i++)
    	{
    		for (int j = 0; j < n; j++)
    		{
    			cout << trace[i][j] << '	';
    		}
    		cout << endl;
    	}
    	cout << "------------" << endl;
    }
    
    void visit(int x, int y, int step)
    {
    	trace[x][y] = step;
    	//printT();
    	if (m*n == step)
    	{
    		countN++;
    		printT();
    		return;
    	}
    	int nextx, nexty;
    	for (int i = 0; i < 8; i++)
    	{
    		nextx = x + changedir[i][0];
    		nexty = y + changedir[i][1];
    		if (nextx < 0 || nextx>(m-1) || nexty < 0 || nexty>(n-1)|| trace[nextx][nexty]!=0)
    		{
    			continue;
    		}
    		visit(nextx, nexty, step + 1);
    		trace[nextx][nexty] = 0;
    	}
    }
    
    
    
    void main()
    {
    
    	int firstX , firstY ;
    	cout << "输入起始位置(棋盘的左上角编号位置(0,0)):" << endl;
    	cin >> firstX >> firstY;
    	//printT();
    	visit(firstX, firstY, 1);
    	cout << "Count " << countN << endl;
    }

    思考:此题也是递归回溯的思想。当确定一个位置之后,要考虑8种可以跳马的方向,设置一个记步数的变量step,当step为25时退出递归,同时把最后确定的一个位置,即写着25的格子的变量重置为0,同时退回到第24步,去寻找其它第25步的可能位置。

    结果:

  • 相关阅读:
    设计原则
    最小路径和--p64--动态规划
    ssm实现数据库关键信息的动态加载
    最大二叉树--p654--递归构造
    城市天际线--p807
    长url转短url--p535
    从中序与后序遍历中构造二叉树-p106--数组,二叉树遍历
    n皇后问题--p52--回溯
    Markdown(editormd)语法解析成HTML
    NFA的实现
  • 原文地址:https://www.cnblogs.com/oneDongHua/p/14264044.html
Copyright © 2020-2023  润新知