御坂19090 发表于 2023-2-20 23:14:54

自己试着写了一下马踏棋盘,看了好几个小时了。真的看不出问题

这个是我的代码#include <stdio.h>
#include <time.h>

#define X 8
#define Y 8

int chess;    //记录棋盘

void print() {
    int i, j;
    for (i = 0; i < X; i++) {
      for (j = 0; j < Y; j++) {
            printf("%2d", chess);
      }
      putchar('\n');
    }
}

//根据xy坐标,判断指定位置可不可走,如果可走改变传入的x y坐标
int decide_next(int* px, int* py, int count) {
    int x = *px, y = *py;

    switch (count) {
    case 0:
      if (x + 2 < X && y - 1 >= 0 && chess == 0) {
            *px = x + 2;
            *py = y - 1;
            return 1;
      }
      break;
    case 1:
      if (x + 2 < X && y + 1 < Y && chess == 0) {
            *px = x + 2;
            *py = y + 1;
            return 1;
      }
      break;
    case 2:
      if (x + 1 < X && y - 2 >= 0 && chess == 0) {
            *px = x + 1;
            *py = y - 2;
            return 1;
      }
      break;
    case 3:
      if (x + 1 < X && y + 2 < Y && chess == 0) {
            *px = x + 1;
            *py = y + 2;
            return 1;
      }
      break;
    case 4:
      if (x - 2 >= 0 && y - 1 >= 0 && chess == 0) {
            *px = x - 2;
            *py = y - 1;
            return 1;
      }
      break;
    case 5:
      if (x - 2 >= 0 && y + 1 < Y && chess == 0) {
            *px = x - 2;
            *py = y + 1;
            return 1;
      }
      break;
    case 6:
      if (x - 1 >= 0 && y - 2 >= 0 && chess == 0) {
            *px = x - 1;
            *py = y - 2;
            return 1;
      }
      break;
    case 7:
      if (x - 1 >= 0 && y + 2 < Y && chess == 0) {
            *px = x - 1;
            *py = y + 2;
            return 1;
      }
      break;
    default:
      break;
    }
    return 0;
}
// 获得棋子的路径
int setHorse(int x, int y, int tag){
    int x1, y1, resule = 0, count = 0;

    // tag记录轨迹
    chess = tag;
    if (tag == 62) {
      tag = 62;
    }
    // 如果tag等于64打印棋盘
    if (tag == X * Y) {
      return 1;
    }

    // 递归进入下一个坐标
    while (count < 8){
      
      // 尝试路径是否能走
      resule = decide_next(&x1, &y1, count);
      if (!resule) {
            count += 1;
      }
      for (x1 = x, y1 = y; resule == 0 && count < 8; count += 1) {
            resule = decide_next(&x1, &y1, count);
      }
      // 返回1表示成功找到路径;对新的点进行尝试
      if (setHorse(x1, y1, tag + 1))
      {
            return 1;
      }
      // 如果失败并且有没尝试的路径,回到上一步重新尝试
      count += 1;
    }
    // 如果全部路径都尝试过,并且没有返回1,说明这个点没有可行的路径,回到上一步并且去除痕迹
    chess = 0;

    return 0;
}

int main(void){
    int i, j, x, y;
    clock_t start, finish;

    for (i = 0; i < X; i++) {
      for (j = 0; j < Y; j++){
            chess = 0;
      }
    }

    // 获取初始坐标;建议(2,0)
    printf("请输入初始坐标(x y):");
    scanf_s("%d %d", &x, &y);

    // 记录开始时间
    start = clock();

    if (setHorse(x, y, 1)) {
      print();
    }
    else{
      printf("可惜无解!\n");
    }

    // 记录结束时间
    finish = clock();

    printf("\n本次计算一共耗时∶%f秒\n", (double)(finish - start) / CLOCKS_PER_SEC);

    return 0;
}

这一段代码// 获得棋子的路径
int setHorse(int x, int y, int tag){
    int x1, y1, resule = 0, count = 0;

    // tag记录轨迹
    chess = tag;
    if (tag == 62) {
      tag = 62;
    }
    // 如果tag等于64打印棋盘
    if (tag == X * Y) {
      return 1;
    }

    // 递归进入下一个坐标
    while (count < 8){
      
      // 尝试路径是否能走
      resule = decide_next(&x1, &y1, count);
      if (!resule) {
            count += 1;
      }
      for (x1 = x, y1 = y; resule == 0 && count < 8; count += 1) {
            resule = decide_next(&x1, &y1, count);
      }
      // 返回1表示成功找到路径;对新的点进行尝试
      if (setHorse(x1, y1, tag + 1))
      {
            return 1;
      }
      // 如果失败并且有没尝试的路径,回到上一步重新尝试
      count += 1;
    }
    // 如果全部路径都尝试过,并且没有返回1,说明这个点没有可行的路径,回到上一步并且去除痕迹
    chess = 0;

    return 0;
}
改成nt setHorse(int x, int y, int tag)
{
      int x1 = x, y1 = y, flag = 0, count = 0;

      // tag记录轨迹
      chess = tag;
      // 如果tag等于64退出程序
      if (tag == X*Y)
      {
                return 1;
      }

      // 如果可以走,那么flag为1
      flag = next(&x1, &y1, count);
      // 否则尝试其他路径
      while (flag == 0 && count < 7)
      {
                count += 1;
                flag = next(&x1, &y1, count);
      }

      // 递归进入下一个坐标
      while (flag)
      {
                // 返回1表示成功找到落脚点
                if (setHorse(x1, y1, tag+1))
                {
                        return 1;
                }
                // 否则从上一步重新尝试
                x1 = x;
                y1 = y;
                count += 1;
                flag = next(&x1, &y1, count);
                while (flag == 0 && count < 7)
                {
                        count += 1;
                        flag = next(&x1, &y1, count);
                }
      }

      if (flag == 0)
      {
                chess = 0;
      }

      return 0;
}就可以。不知道问题在哪里。想知道是哪里错误了?

人造人 发表于 2023-2-21 21:14:06

sh-5.1$ cat main.c
#include <stdio.h>
#include <time.h>

#define X 8
#define Y 8

int chess; // 记录棋盘

void print(void) {
    int i, j;
    for(i = 0; i < X; i++) {
      for(j = 0; j < Y; j++) {
            printf("%2d", chess);
      }
      putchar('\n');
    }
}

// 根据xy坐标,判断指定位置可不可走,如果可走改变传入的x y坐标
int decide_next(int *px, int *py, int count) {
    int x = *px, y = *py;

    switch(count) {
    case 0:
      if(x + 2 < X && y - 1 >= 0 && chess == 0) {
            *px = x + 2;
            *py = y - 1;
            return 1;
      }
      break;
    case 1:
      if(x + 2 < X && y + 1 < Y && chess == 0) {
            *px = x + 2;
            *py = y + 1;
            return 1;
      }
      break;
    case 2:
      if(x + 1 < X && y - 2 >= 0 && chess == 0) {
            *px = x + 1;
            *py = y - 2;
            return 1;
      }
      break;
    case 3:
      if(x + 1 < X && y + 2 < Y && chess == 0) {
            *px = x + 1;
            *py = y + 2;
            return 1;
      }
      break;
    case 4:
      if(x - 2 >= 0 && y - 1 >= 0 && chess == 0) {
            *px = x - 2;
            *py = y - 1;
            return 1;
      }
      break;
    case 5:
      if(x - 2 >= 0 && y + 1 < Y && chess == 0) {
            *px = x - 2;
            *py = y + 1;
            return 1;
      }
      break;
    case 6:
      if(x - 1 >= 0 && y - 2 >= 0 && chess == 0) {
            *px = x - 1;
            *py = y - 2;
            return 1;
      }
      break;
    case 7:
      if(x - 1 >= 0 && y + 2 < Y && chess == 0) {
            *px = x - 1;
            *py = y + 2;
            return 1;
      }
      break;
    }
    return 0;
}

// 获得棋子的路径
int setHorse(int x, int y, int tag) {
    //int x1, y1, resule = 0, count = 0;
    int x1, y1, count = 0;

    // tag记录轨迹
    chess = tag;


#if 0
    // ???
    // 这是在做什么?
    if(tag == 62) {
      tag = 62;
    }
#endif


    // 如果tag等于64打印棋盘
    if(tag == X * Y) {
      return 1;
    }

    // 递归进入下一个坐标
    while(count < 8) {

      // 尝试路径是否能走
      x1 = x; y1 = y;
      //if(!decide_next(&x1, &y1, count)) {++count; continue;}
      /*
      resule = decide_next(&x1, &y1, count);
      if(!resule) {
            count += 1;
      }
      */
      /*
      // 这个for循环是在做什么?
      // 这里需要两层循环吗?
      for(x1 = x, y1 = y; resule == 0 && count < 8; count += 1) {
            resule = decide_next(&x1, &y1, count);
      }
      */
      // 返回1表示成功找到路径;对新的点进行尝试
      if(decide_next(&x1, &y1, count)) {
            if(setHorse(x1, y1, tag + 1)) return 1;
      }
      // 如果失败并且有没尝试的路径,回到上一步重新尝试
      count += 1;
    }
    // 如果全部路径都尝试过,并且没有返回1,说明这个点没有可行的路径,回到上一步并且去除痕迹
    chess = 0;

    return 0;
}

int main(void) {
    int i, j, x, y;
    clock_t start, finish;

    for(i = 0; i < X; i++) {
      for(j = 0; j < Y; j++) {
            chess = 0;
      }
    }

    // 获取初始坐标;建议(2,0)
    printf("请输入初始坐标(x y):");
    //scanf_s("%d %d", &x, &y);
    scanf("%d%d", &x, &y);

    // 记录开始时间
    start = clock();

    if(setHorse(x, y, 1)) {
      print();
    } else {
      printf("可惜无解!\n");
    }

    // 记录结束时间
    finish = clock();

    printf("\n本次计算一共耗时∶%f秒\n", (double)(finish - start) / CLOCKS_PER_SEC);

    return 0;
}
sh-5.1$ ./main
请输入初始坐标(x y):1 1
5348513855406136
50   1544760375641
1152494439583562
219125946334257
1310452043286334
18   316   726233229
914   52421302764
417   815   6252231

本次计算一共耗时∶1.926012秒
sh-5.1$

ExiaGN001 发表于 2023-2-21 22:00:29

人造人 发表于 2023-2-21 21:14


然而他的意图是debug而不是做题

ExiaGN001 发表于 2023-2-21 22:36:44

原先的代码栈溢出挂掉了。
问题还在看。
先指出几点明确的:
count有高亮,不要乱用作标识符
中间有一个意义不明的“如果tag==62就把tag=62”,人家都等于62了,就不用赋值成62了

御坂19090 发表于 2023-2-22 20:49:28

ExiaGN001 发表于 2023-2-21 22:36
原先的代码栈溢出挂掉了。
问题还在看。
先指出几点明确的:


那个tag是设置断点的
页: [1]
查看完整版本: 自己试着写了一下马踏棋盘,看了好几个小时了。真的看不出问题