• 回溯法解马的遍历问题


      马的遍历问题:在n*m的棋盘上,马只能走日字。马从位置(x,y)处出发,把棋盘的每一点都走一次,且只走一次,找出所有路径。

    问题分析:行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个点。用递归容易实现。

    注意:问题要求找出所有可能的解。就要注意回溯过程的清理现场工作,就是置当前位置为未经过。

    数据结构设计:用一个变量dep记录递归深度,也就是走过的点数。当dep=n*m;找到一组解。

    用n*m的二维数组记录马走过的过程,初始值为0表示未经过,起点存储的是1,终点存储的是n*m。

    #include<iostream>
    using namespace std;
    void output();
    int n=5,m=4;
    int fx[8]={1,2,2,1,-1,-2,-2,-1};
    int fy[8]={2,1,-1,-2,-2,-1,1,2};
    int a[5][4]; //下标从1开始
    int dep,x,y,count;
     
    bool check(int x,int y)
    {
         if(x>=1&&x<=n&&y>=1&&y<=m&&(!a[x][y]))
             return true;
         else
             return false;
    
    }
        
    void find(int x,int y,int dep)
    {
        int i,xx,yy;
        for(i=1;i<=8;i++) //加上方向增量,形成新的坐标
        {
            xx=x+fx[i];
            yy=y+fy[i];
            if(check(xx,yy)) //判断新坐标是否出界,是否已走过
            {
                a[xx][yy]=dep; 
                if(dep==n*m)
                    output();
                else
                    find(xx,yy,dep+1);
    
                
               a[xx][yy]=0; //回溯,恢复未走未走
                
            }
             
        }
    }
    
    void output()
    {
        count++;
        cout<<"\n";
        cout<<"count="<<count;
        for(y=1;y<=n;y++)
        {
            cout<<endl;
            for(x=1;x<=m;x++)
                cout<<a[y][x]<<ends;
        }
    }
    
    int main()
    {
        int i,j;
        count=0;
        dep=1;
        cout<<"please input x,y";
        cin>>x>>y;
        if(x>n||y>m||x<1||y<1)
        {
            cout<<"input error";
            return -1;
        }
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                a[i][j]=0;
        a[x][y]=1;
        find(x,y,2);
        if(count==0)
            cout<<"no solution!";
        else
            cout<<"nambers of solution="<<count<<endl;
    }
     

    代码输出好像有错误。

    http://zhidao.baidu.com/question/44427050.html

  • 相关阅读:
    Linux启动或禁止SSH用户及IP的登录
    How to Setup Chroot SFTP in Linux (Allow Only SFTP, not SSH)
    vsftp被动模式启用iptables访问设置
    关于使用Element.getNodeValue()返回NULL的问题
    Quartz 有状态的JobDataMap
    log4j学习日记-写入数据库
    LeetCode 551. Student Attendance Record I (学生出勤纪录 I)
    LeetCode 680. Valid Palindrome II (验证回文字符串 Ⅱ)
    LeetCode 125. Valid Palindorme (验证回文字符串)
    LeetCode 541. Reverse String II (反转字符串 II)
  • 原文地址:https://www.cnblogs.com/youxin/p/2541858.html
Copyright © 2020-2023  润新知