马踏棋盘算法递归+回溯法实现 C语言

r为矩阵的行,c为矩阵的列

将结果输出到当前目录下的results.txt(需要提前建好)。

结果将给出:1.是否存在路径使马可以按要求走遍所有的方格;

2.解的总数;

3.程序执行的时间;

    #include<stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define r 2
    #define c 4

    int flag[r][c]={0};//存放马跳路径的二维数组
    int arr[r][c]={0};
    int x[8]={2,1,-1,-2,2,1,-1,-2};
    int y[8]={1,2,2,1,-1,-2,-2,-1};
    int n=1,count;
    FILE *fp;

    //初始化文件输出流
    int initOut()
    {
        fp=fopen("results.txt","w");  //记得关闭
        if(fp==NULL)
        {
            printf("File cannot open! " );
            exit(0);
        }
        return 0;
    }

    //添加一个判断函数,判断这样的哈密顿路径是否存在
    void judgeExistence(){
        if(count==0)
            printf("%d * %d 的棋盘不存在能使得马可以不重复遍历完棋盘中每一格的路径\n",r,c);
    }

    //输出马跳的步骤stepOut()
    void stepOut(){
                for(int a=0;a<r;a++){
               for(int b=0;b<c;b++)
                   {
                    fprintf(fp,"%3d ",arr[a][b]);
                   }
               fprintf(fp,"\n");
            }
          fprintf(fp,"\n");
    }

    void DFS(int i,int j)
    {
        if(n==r*c)
        {
            count++;
            stepOut();//写个函数,输出马跳的步骤stepOut()
        }

        else
          for(int k=0;k<8;k++)
          {
            if(i+x[k]>=0&&i+x[k]<r&&j+y[k]>=0&&j+y[k]<c&&flag[i+x[k]][j+y[k]]==0)
            {
                flag[i+x[k]][j+y[k]]=1;n++;
                arr[i+x[k]][j+y[k]]=n;//给记录马跳步骤的矩阵赋值

                DFS(i+x[k],j+y[k]);//循环+递归

                flag[i+x[k]][j+y[k]]=0;n--;
            }
        }
    }  

    void main()
    {
        clock_t start, finish;  //计算程序一共花费了多少时间
        long duration;
        start=clock();

        count=0;
        int X,Y;
        label_1:printf("请输入马初始横坐标(X<=%d):X=\n",r);
        scanf("%d",&X);
        if(X>r){
            printf("请输入小于等于%d的数\n",r);
            goto label_1;
        }
        label_2:printf("请输入马初始纵坐标(Y<=%d):Y=\n",c);
        scanf("%d",&Y);
        if(Y>c){
            printf("请输入小于等于%d的数\n",c);
            goto label_2;
        }
        X=X-1;
        Y=Y-1;
        flag[X][Y]=1;
        arr[X][Y]=1;

        initOut();
        DFS(X,Y);
        judgeExistence();
        fprintf(fp,"解的总数为:%d\n",count); 

        finish=clock();
        duration=finish-start;//程序执行的时间,单位毫秒
        fprintf(fp,"程序执行的时间为:%10ld ms\n",duration);
        fclose(fp);
    }

代码中有哪些不正确的地方欢迎大家指正。

时间: 2024-07-31 12:55:00

马踏棋盘算法递归+回溯法实现 C语言的相关文章

回溯算法(马踏棋盘)

近期学习了回溯算法于是自己写了马踏棋盘的递归以及非递归方式的代码: 运行效果如下: (本人水平有限,若有不足之处欢迎大家交流)

马踏棋盘(骑士周游问题)

马踏棋盘问题(骑士周游问题) 实际上是图的深度优先搜索(DFS)的应用. 如果使用回溯(就是深度优先搜索)来解决,假如马儿踏了53个点,如图:走到了第53个,坐标(1,0),发现已经走到尽头,没办法,那就只能回退了,查看其他的路径,就在棋盘上不停的回溯-- ,思路分析+代码实现 使用贪心算法(greedyalgorithm)进行优化.解决马踏棋盘问题. /** * 〈马踏棋盘 算法〉 * * @author LZ * @create 2019/9/29 * @since 1.0.0 */ pub

马踏棋盘递归所有解

这次马踏棋盘是用递归实现的,而且可以弄出来所有解,当时电脑跑的最快的都有40多万解了,这个也可以看你电脑cpu好坏,一般超级本跑不动.这是实际上和八皇后是同一种性质的问题,都用到了回溯的思想,有接进行下一个,不行了退回去,在进行尝试.不多说了,直接上代码: #include<stdio.h> #include <stdlib.h> #include<conio.h> #define N 8 int cnt=1; // 记录马的位置 int n=1; int chess[

马踏棋盘问题-贪心(matlab&amp;c++)

1.问题描述 将马随机放在国际象棋的Board[0-7][0-7]的某个方格中,马按走棋规则进行移动,走遍棋盘上全部64个方格.编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8×8的方阵,输出之. 2.matlab代码 clear all clc chessboard=zeros(8);%初始化 DirX=[2 1 -1 -2 -2 -1 1 2];%方向向量 DirY=[1 2 2 1 -1 -2 -2 -1]; stack(1).x=0; stack

马踏棋盘的c语言实现(一.遍历法)

题目很简单呀!!! 在国际象棋的棋盘上,将马随意放置,之后走日字,走完即可. 要求:8×8的棋盘 遍历算法: 可以说是碰运气,当你确定在某一位置时,根据规则你自然有了八种选择,                   2   3          1       4           H           8       6         7   5                                         分别是 X=   {i-2, i-1, i+1, i+2, i+

八皇后问题——递归+回溯法

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 高斯认为有76种方案.1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果. 求解过程: 采用遍历的办法,就是采用将每种情况都验证的办法最终找出问题的解,但是蛮力遍历的话,需要遍历的数据量太大,计算时间花费太大,所以在遍历

剑指Offer_12_矩阵中的路径(参考问题:马踏棋盘)

题目描述  请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子. 例如: a   b  c   e s   f   c   s  a  d   e   e  矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后

逃离大厦第80关与马踏棋盘

今天我在玩一款逃离大厦的解密游戏.在跨越了重重障碍来到了第八十关.这一关很有意思 每次点击都会直接冲到底,要求填满所有空白的地方. 本来很容易,但是很不幸,一旦点击了就不能修改,楼主于是想到了马踏棋盘,终于可以学以致用了于是毫不犹豫 上代码 #include <stdio.h> #include <stdlib.h> #define N 5+2 typedef struct { int a[N][N]; int lstep[4]; int rstep[4]; int cnt; }H

五大经典算法之回溯法

一.基本概念 ??回溯法,又称为试探法,按选优条件向前不断搜索,以达到目标.但是当探索到某一步时,如果发现原先选择并不优或达不到目标,就会退回一步重新选择,这种达不到目的就退回再走的算法称为回溯法. 与穷举法的区别和联系: 相同点:它们都是基于试探的. 区别:穷举法要将一个解的各个部分全部生成后,才检查是否满足条件,若不满足,则直接放弃该完整解,然后再尝试另一个可能的完整解,它并没有沿着一个可能的完整解的各个部分逐步回退生成解的过程.而对于回溯法,一个解的各个部分是逐步生成的,当发现当前生成的某