Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 631|回复: 0

马走“日”字问题的回溯算法实现 java实例

[复制链接]

该用户从未签到

发表于 2011-9-18 16:34:34 | 显示全部楼层 |阅读模式
(1) 问题描述
马的遍历问题。
     在n*m的棋盘中,马只能走"日"字。马从位置(x,y)出发,把棋盘的每一格都走一次且只走一次。找出所有路径。

(2) 问题分析

   马是在棋盘的点上行走的,所以这里的棋盘是指行有N条边、列有M条边。而一个马在不出边界的情况下有8个方向
可以行走(走"日"字),如当前坐标为(x,y),则行走后的坐标可以为:
(x+1, y+2)
(x+1, y-2)
(x+2, y+1)
(x+2, y-1)
(x-1, y-2)
(x-1, y+2)
(x-2, y-1)
(x-2, y+1)
  
     搜索的解空间是整个棋盘上的n*m个点。
    约束条件是不出边界且每个点只经过一次。
    搜索过程是从任一点(x,y)出发,按照深度优先的原则,从8个方向中尝试一个可以走的点,直到走过棋盘上所有
n*m个点。

(3)程序

/**  
* create on 2010.05.21 TODO 回溯算法  
*   
* @author 毛正吉  
* @version v1.0  
*   
*/  
public class RecollectionSearch {   
  
    /**  
     * @param args  
     */  
    public static void main(String[] args) {   
        // 注意(0<=x< n && 0<=y< m)   
        int n = 5;   
        int m = 4;   
        int x = 0;   
        int y = 0;   
        RecollectionSearch rs = new RecollectionSearch(n, m, x, y);   
        rs.find(x, y, 2);   
        System.out.println("######################");   
        System.out.println("总解数count=" + rs.getCount());   
        System.out.println("######################");   
  
    }   
  
    // 棋盘行数   
    private int n;   
    // 棋盘列数   
    private int m;   
    // 马的起始x坐标   
    private int x;   
    // 马的起始y坐标   
    private int y;   
    // 棋盘坐标   
    private int[][] a;   
    // 求解总数   
    private int count;   
    // "日"子x坐标   
    public int[] fx = { 1, 2, 2, 1, -1, -2, -2, -1 };   
    // "日"子y坐标   
    public int[] fy = { 2, 1, -1, -2, -2, -1, 1, 2 };   
  
    /**  
     * 构造方法  
     *   
     * @param _n  
     * @param _m  
     * @param _x  
     * @param _y  
     */  
    public RecollectionSearch(int _n, int _m, int _x, int _y) {   
        n = _n;   
        m = _m;   
        x = _x;   
        y = _y;   
        a = new int[n][m];   
        for (int i = 0; i < n; i++) {   
            for (int j = 0; j < m; j++) {   
                a[j] = 0;   
            }   
        }   
        // 马的起点 a[x][y]=k表示马的第k步
        a[x][y] = 1;   
        count = 0;   
    }   
  
    public void find(int x, int y, int dep) {   
        int i, xx, yy;   
        for (i = 0; i < 8; i++) {   
            xx = x + fx;   
            yy = y + fy;   
            // 判断新坐标是否出界,是否已走过   
            if (check(xx, yy) == 1) {   
                a[xx][yy] = dep;   
                if (dep == n * m) {   
                    output();   
                } else {   
                    // 从新坐标出发,递归下一层   
                    find(xx, yy, dep + 1);   
                }   
                // 回溯,恢复未走标志   
                a[xx][yy] = 0;   
            }   
        }   
    }   
  
    /**  
     * 判断新坐标是否出界,是否已走过  
     *   
     * @param xx  
     * @param yy  
     * @return  
     */  
    public int check(int xx, int yy) {   
        if (xx >= n || yy >= m || xx < 0 || yy < 0 || a[xx][yy] != 0) {   
            return 0;   
        }   
        return 1;   
    }   
  
    /**  
     * 输出结果  
     */  
    public void output() {   
        count++;   
        System.out.println("count=" + count);   
        for (int y = 0; y < n; y++) {   
            System.out.println("");   
            for (int x = 0; x < m; x++) {   
                System.out.printf("%4d",a[y][x]);   
            }   
        }   
        System.out.println("");   
    }   
  
    public int getN() {   
        return n;   
    }   
  
    public void setN(int n) {   
        this.n = n;   
    }   
  
    public int getM() {   
        return m;   
    }   
  
    public void setM(int m) {   
        this.m = m;   
    }   
  
    public int getCount() {   
        return count;   
    }   
  
    public void setCount(int count) {   
        this.count = count;   
    }   
  
    public int getX() {   
        return x;   
    }   
  
    public void setX(int x) {   
        this.x = x;   
    }   
  
    public int getY() {   
        return y;   
    }   
  
    public void setY(int y) {   
        this.y = y;   
    }   
}  

运行:


count=3
.........................................略..................................................................
count=32

1   6   17   12
18 13  8    5
7   2   11   16
14 19 4     9
3   10 15   20
######################
总解数count=32
######################
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2024-5-23 22:56 , Processed in 0.335770 second(s), 35 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表