免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6686 | 回复: 16
打印 上一主题 下一主题

关于马踏棋盘问题的求教 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-12-31 11:39 |只看该作者 |倒序浏览
最近看了马踏棋盘问题,突然比较感兴趣,写了段程序,主要思路是这样的
/*Analyse:               
        1.init chessboard
        2.start from (0.0) and try direction from 0
        3.if can_go,go next;if can't,try another direction
        4.if have try all the direction, go back old one and init the current point
        5.if try all the direction of start point(0.0),return can't find, otherwise print the chessboard*/

突然想深入了解这个问题,对于n*n的棋盘,求共有多少种走法.要求用C来实现,不知道大家有什么想法.谢谢.

论坛徽章:
0
2 [报告]
发表于 2004-12-31 13:58 |只看该作者

关于马踏棋盘问题的求教

本人新手,在此块讨论区人微言轻,本不敢谈什么个人的看法.
但我以前写过类似的程序,
我做的题是8*8,选择任意点为起点马踏完成,记录每一步.
从理论上来说用递归算法是可以的,但是在TC环境下是得不出答案的
因为递归后,一步一步尝试使递归层越陷越深,不知道怎么的就死了
(哪位能告诉我什么原因吗?)
最后我找到一种方法
就是不论以哪个点为始点,我都向外围靠,走完外圈再走内圈
所以不论哪个点为始点都能走通.
至于N*N还没有尝试过.
问一下你的程序运行了吗?

论坛徽章:
0
3 [报告]
发表于 2005-01-02 10:24 |只看该作者

关于马踏棋盘问题的求教

深度优先的递归遍历适于求解那些简单问题,因为情况复杂之后,递归深度太大,将造成堆栈耗尽。
比较复杂的问题适于采用广度优先的遍历。如果情况进一步复杂,还可以在广度节点扩展的时候加入启发函数,进行a*遍历。

方法与深度优先差不多,只不过把栈换成队列即可。

论坛徽章:
0
4 [报告]
发表于 2005-01-02 14:46 |只看该作者

关于马踏棋盘问题的求教

本科的数据结构教材里有这个习题,原题是马的遍历:从任一起点均可无重复遍历棋盘的所有落子点。

算法比较简单,主要考虑遍历策略,因为走下一步最多有八种可能方法,我的遍历策略是择优遍历下一步的下一步所能选择的方法最少的走法,可以想象靠边的点的走法最少,所以遍历路线是从外到内。

我这里有源码,如果楼主需要可以放上来。

论坛徽章:
0
5 [报告]
发表于 2005-01-04 15:32 |只看该作者

关于马踏棋盘问题的求教

谢谢大家帮忙,我也些了个程序,通过限制递归的次数来解决这个问题,在这里我限制的递归次数为100000,我还想知道知道如果求解6*6或者8*8棋盘可能的解的个数,
这是我的程序,写的比较烂,请大家指教
/* 要求:
  1.依次输出所走过的各位置的坐标。
  2.画出棋盘的图形形式,并在其上动态的标注行走过程。
  3.程序能方便的移植到其他规格的棋盘上。*/
/*Analyse:               
        1.init chessboard
        2.start from (0.0) and try from direction 0
        3.if can_go,go next;if can't,try another direction
        4.if have try all the direction, go back old one and init the current point
        5.if try all the direction of start point(0.0),return can't find, otherwise print the chessboard*/
#include <time.h>;

#define xSize 8
#define ySize 8
#define MAXSTEP 100000
int iStep = 0;
long allStep = 0;
int xRecord = 0,yRecord = 0;
int chessboard[xSize][ySize][2];//define chessboard;[0]--count,[1]--direction

int init_chess()//init chessboard
{
        int i,j;
        for(i=0;i<xSize;i++)
                for(j=0;j<ySize;j++)
                {
                        chessboard[j][0]=0;//init count
                        chessboard[j][1]=0;//init direction
                }
}
int print_chess()//print chessboard
{
        int i,j;
        for(i=0;i<xSize;i++)
        {
                for(j=0;j<ySize;j++)
                        printf("%4d",chessboard[j][0]);
                printf("\n\n";
        }
}
int search_x(int count)//search xPoint by count
{
        int i,j;
        for(i=0;i<xSize;i++)
                for(j=0;j<ySize;j++)
                        if(chessboard[j][0]==count)
                                return i;
        return 0;
}
int search_y(int count)//search yPoint by count
{
        int i,j;
        if(count==0)
                return 0;
        for(i=0;i<xSize;i++)
                for(j=0;j<ySize;j++)
                        if(chessboard[j][0]==count)
                                return j;
        return 0;
}
int can_go(int m,int n)//
{
        /*find if it out board or have been gone*/
        if((m>;=0&&m<xSize&&n>;=0&&n<ySize)&&(chessboard[m][n][0] == 0))
                return 1;//can go
        else
                return 0;//can't go
}

int go_back(int i,int j)
{
        int m,n;
        //find old one(m,n)
        m = search_x(chessboard[j][0]-1);
        n = search_y(chessboard[j][0]-1);
        //(m,n) direction++
        ++chessboard[m][n][1];

        //clear(i,j)
        chessboard[j][0] = 0;
        chessboard[j][1] = 0;
       
        //go from(m,n)
        //printf("go back to i=%d,j=%d,count=%d\n",m,n,chessboard[m][n][0]);
        go(m,n);
}
int go(int i,int j)
{
        int level = 0 , count = 0 ;
        int m,n;
       
        level = chessboard[j][1];
        count = chessboard[j][0];
        if(count == (xSize*ySize)-1)
        {
                iStep = -1;
                return;
        }
       
        iStep++;
        allStep++;
        if(iStep >; MAXSTEP)
        {
                xRecord = i;
                yRecord = j;
                iStep = 0;
                return;
        }
        switch(level)
        {
        case 0:
                m = i-2;
                n = j+1;
                break;
        case 1:
                m = i-1;
                n = j+2;
                break;
        case 2:
                m = i+1;
                n = j+2;
                break;
        case 3:
                m = i+2;
                n = j+1;
                break;
        case 4:
                m = i+2;
                n = j-1;
                break;
        case 5:
                m = i+1;
                n = j-2;
                break;
        case 6:
                m = i-1;
                n = j-2;
                break;
        case 7:
                m = i-2;
                n = j-1;
                break;
        default:/*if can't find next go to back to first.*/
                //if(i==0&&j==0)/*search all but can't find*/
                //{
                //        printf("Can't find any trace";
                //        return;
                //}
                go_back(i,j);
                return;       
        }
        if(can_go(m,n) == 1)
        {
                chessboard[m][n][0] = ++count;
                //printf("can go.allStep=%d,iStep=%d,i=%d,j=%d,level=%d,count=%d\n",allStep,iStep,i,j,chessboard[j][1],chessboard[j][0]);
                go(m,n);
        }
        else
        {
                chessboard[j][1] = ++level;
                //printf("can't go.allStep=%diStep=%d,i=%d,j=%d,level=%d,count=%d\n",allStep,iStep,i,j,chessboard[j][1],chessboard[j][0]);
                go(i,j);
        }
}

//#define CLOCKS_PER_SEC 1000000
int main()
{
        int i;
        clock_t time;
        //printf("time=%d",time);
        //Init chessboard

        init_chess();
       
        //go from (0.0)
        //go(0,0);
        do
        {
                go(xRecord,yRecord);
        }while(iStep != -1);
       
        time = clock();
        printf("Search OK,allStep=%d\n,time=%d\n",allStep,time/CLOCKS_PER_SEC);

        //print go trace
        print_chess();
}

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2005-01-04 18:44 |只看该作者

关于马踏棋盘问题的求教

如果是5*5的棋盘,结果是多少种啊?

论坛徽章:
0
7 [报告]
发表于 2005-01-05 00:37 |只看该作者

关于马踏棋盘问题的求教

[quote]原帖由 "aero"]如果是5*5的棋盘,结果是多少种啊?[/quote 发表:


我写的程序说有304种.

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
8 [报告]
发表于 2005-01-05 08:50 |只看该作者

关于马踏棋盘问题的求教

原帖由 "JohnBull" 发表:


我写的程序说有304种.


^_^,那就对了。偶写的是304种,可是在网上搜的一个论坛上的一篇帖子中提到是1000多种。怕自己错了。

JohnBull都说了,那一定没错了。超相信JohnBull老大的算法。

论坛徽章:
0
9 [报告]
发表于 2005-01-05 11:49 |只看该作者

关于马踏棋盘问题的求教

原帖由 "aero" 发表:


^_^,那就对了。偶写的是304种,可是在网上搜的一个论坛上的一篇帖子种提到是1000多种。怕自己错了。

JohnBull都说了,那一定没错了。超相信JohnBull老大的算法。


OK! Buddy!
right together, wrong together!  :em11:

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
10 [报告]
发表于 2005-01-05 13:37 |只看该作者

关于马踏棋盘问题的求教

偶怎么得出来有30000多种?
  1. #include <stdio.h>;

  2. struct _steps {
  3.     int nextX;
  4.     int nextY;
  5. }steps[] = {
  6.     {-2, -1},
  7.     {-2, 1},
  8.     {-1, -2},
  9.     {-1, 2},
  10.     {1, -2},
  11.     {1, 2},
  12.     {2, -1},
  13.     {2, 1}
  14. };
  15. int nSize, nSteps, nCount;
  16. int startx=0, starty=0;
  17. char **Board;

  18. typedef struct stepstack{
  19.     int x;
  20.     int y;
  21.     struct stepstack *next;
  22. }step;

  23. step *head = NULL, *tail = NULL;
  24. step **pStep = & head ;

  25. int InitBoard()
  26. {
  27.     int i, j;
  28.     Board = (char **)malloc(nSize * sizeof(char *));
  29.     if(Board == NULL) return -1;
  30.     for(i = 0; i < nSize; i++) {
  31.         Board[i] = (char *)malloc(nSize);
  32.         if(Board[i] == NULL) return -2;
  33.         for(j = 0; j < nSize; j++)
  34.             Board[i][j] = 0;
  35.     }
  36.     return 0;
  37. }

  38. void FindPoint(int a, int b, int x, int y)
  39. {
  40.     int i, nextA, nextB, nNum;
  41.     step  *newstep, *oldstep, *steplist;

  42.     nNum = 0;
  43.     for(i = 0; i < 8; i++) {
  44.         nextA = a + steps[i].nextX;
  45.         nextB = b + steps[i].nextY;
  46.         if(nextA < 0 || nextA >;= nSize || nextB < 0 || nextB >;= nSize) continue;
  47.         if(Board[nextA][nextB] == 1) continue;

  48.         oldstep = tail;
  49.         newstep = (step *)malloc(sizeof(step));
  50.         newstep->;x = a;
  51.         newstep->;y = b;
  52.         newstep->;next = NULL;
  53.         tail = newstep;
  54.         *pStep = newstep;
  55.         pStep = &(newstep->;next);

  56.         Board[a][b] = 1;
  57.         nSteps++;
  58.         if(nextA == x && nextB == y) {
  59.             printf("STEPS[%d]:", nSteps);
  60.             for(steplist=head; steplist != NULL; steplist = steplist->;next) {
  61.                 printf("(%d, %d)==>;",  steplist->;x, steplist->;y);
  62.             }
  63.             printf("(%d, %d)\n", x, y);
  64.             nCount++;
  65.         }
  66.         else
  67.             FindPoint(nextA, nextB, x, y);
  68.         Board[a][b]=0;
  69.         nSteps--;
  70.         free(newstep);
  71.         if(oldstep != NULL) {
  72.             oldstep->;next = NULL;
  73.             pStep = &(oldstep->;next);
  74.             tail = oldstep;
  75.         }
  76.         else {
  77.             head = NULL;
  78.             pStep = & head ;
  79.             tail = NULL;
  80.         }
  81.     }
  82.     return;
  83. }

  84. main()
  85. {
  86.     int i, x, y;
  87.     printf("Input the chessboard size:");
  88.     scanf("%d", &nSize);
  89.     if(InitBoard() < 0) {
  90.         printf("memory error.\n");
  91.         exit(-1);
  92.     }
  93.     do {
  94.         printf("Input the target position(x,y):");
  95.         scanf("%d, %d", &x, &y);
  96.     }while(x < 0 || x >;= nSize || y < 0 || y >;= nSize);
  97.     nSteps = 0;
  98.     nCount = 0;
  99.     FindPoint(startx, starty, x, y);
  100.     printf("COUNT:%d\n", nCount);
  101. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP