骑士游历C语言递归,请大家帮忙看下哪里错了,谢谢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了骑士游历C语言递归,请大家帮忙看下哪里错了,谢谢相关的知识,希望对你有一定的参考价值。

如题,骑士游历问题C语言递归
程序如下:
#include <stdio.h>
#define N 8//棋盘大小
int KnightTrav(int i, int x, int y, int chessbord[N][N]);

//8种方向
static int dx[8] = 2, 1, -1, -2, -2, -1, 1, 2;
static int dy[8] = 1, 2, 2, 1, -1, -2, -2, -1;

main()

int i, j, flag, x, y;
static int chessbord[N][N] =0;

printf("Input the initial position x,y:");
scanf("%d,%d", &x, &y);

chessbord[x][y] = 1;//初始位置 置为1

flag = KnightTrav(1, x, y, chessbord);
if (flag)
//通路则矩阵装输出
printf("Output:\n");
for (i=0; i<N; i++)

for (j=0; j<N; j++)

printf("%4d", chessbord[i][j]);

printf("\n");


else

printf("No solution!\n");



int KnightTrav(int i, int x, int y, int chessbord[N][N])
//递归函数
int xx, yy, flag, count = -1;

do
count++;
flag = 0;
xx = x + dx[count];
yy = y + dy[count];
if ((xx>=0 && xx<N) && (yy>=0 && yy<N) && chessbord[xx][yy]==0)

chessbord[xx][yy] = i;
if (i < N*N)

flag = KnightTrav(i+1, xx, yy, chessbord);
if (!flag) chessbord[xx][yy] = 0;

else

flag = 1;


while (!flag && count<8);
return flag;

很着急的呀,希望明晚前得到解答,谢谢
【补充的补充】我不是骗子...大家都很热心地回答,我暂时选不出最佳答案了...
在这里先特别感谢下 ww884203 和 sunlight12346~~
感动啊,一直觉得程序设计这个板块的回答者都比其他板块的更热心呢
【再补充】呵呵~ 烦恼恋爱板块...
可是运行结果是对的呀,如图,还是while (!flag && count<8);//分别尝试8个方向
【接着补充】:
8×8的棋盘11作为起始的时候要计算65531ms才找到路径,必然是回溯了。
需要回溯的话,不就是8个方向都试过无可行方向吗,如果do while的条件里写的是(count<8),做完第8次循环也就是count=7的时候(此时8个方向都已经试过了),那应该还会接着循环做count++得到count=8。count=8的时候,dx[count]和 dy[count]都不知道是什么神奇的数了,于是
xx = x + dx[count]; yy = y + dy[count]; 新坐标xx和yy也就不知道是不是在棋盘里了,不在棋盘里的话,
通过if ((xx>=0 && xx<N) && (yy>=0 && yy<N) && chessbord[xx][yy]==0)这句就把它过滤掉了。
如果在棋盘里结果就不对了...所以说在这里的dx[8]和dy[8]可能使得新坐标(xx,yy)超出了棋盘范围,而得到了正确结果吧?
ww884203,谢谢!向你致敬

简单的帮你改了一下。
首先是你的程序里面的几个毛病。
chessbord[x][y] = 1;//初始位置 置为1

flag = KnightTrav(1, x, y, chessbord);
if (flag)
中间那一行,因为在函数KnightTrav里面,是先把i的值赋给盘面然后再i+1,而你之前已经把初始位置赋值了1,所以会造成如下后果:
1.盘面上有两个1(这还算好的,但是第二种情况把这种都否定了)
2.由于有了两个1,程序算到最后,算到了i=N*N-1的时候,盘面上再没有任何位置可以赋值,因此程序不管怎样算都不对。
然后还有一个我觉得做得不够好的地方。对于我们程序人员来说,知道数组是从0开始的,但是对于用户来说,想要输入第一行,都得输入0,第二行就输入1,不是很奇怪吗?所以我建议把所有的关于数组大小的数字都加上1,比如chessborad[N][N]变成chessborad[N+1][N+1]
然后就是,你的这个程序效率是很低的,所以在棋盘有64个子的情况下,想要算出来是很要等一等的。建议你把N改成5,或者更低,进行试验判断你的代码对不对。
修改后代码如下,测试运行通过,但是N的值大了极难算出来
#include <stdio.h>
#define N 6//棋盘大小
int KnightTrav(int i, int x, int y, int chessbord[N+1][N+1]);//把数组增大

//8种方向
static int dx[8] = 2, 1, -1, -2, -2, -1, 1, 2;
static int dy[8] = 1, 2, 2, 1, -1, -2, -2, -1;

main()

int i, j, flag, x, y;
static int chessbord[N+1][N+1] =0;

printf("Input the initial position x,y:");
scanf("%d,%d", &x, &y);

chessbord[x][y] = 1;//初始位置 置为1

flag = KnightTrav(2, x, y, chessbord); //把1改成2
if (flag)
//通路则矩阵装输出
printf("Output:\n");
for (i=1; i<N+1; i++) //输出的时候就别输出是0的那一行了

for (j=1; j<N+1; j++)

printf("%4d", chessbord[i][j]);

printf("\n");


else

printf("No solution!\n");



int KnightTrav(int i, int x, int y, int chessbord[N+1][N+1])
//递归函数
int xx, yy, flag, count = -1;

do
count++;
flag = 0;
xx = x + dx[count];
yy = y + dy[count];
if ((xx>=1 && xx<N+1) && (yy>=1 && yy<N+1) && chessbord[xx][yy]==0)

chessbord[xx][yy] = i;
if (i < N*N)

flag = KnightTrav(i+1, xx, yy, chessbord);
if (!flag) chessbord[xx][yy] = 0;

else

flag = 1;


while (!flag && count<8);
return flag;

选楼上的吧,他说的count应该小于7是对的。我用do.while比较少,没有注意到,我开始还以为是程序效率问题,所以导致半天算不出来,现在想来,是因为count[8]不知道是几,内存都不知道加到哪里去了。改成7应该就是对的,你可以自己去测试。
PS一个无关的话题,要说最热心的版块我觉得是烦恼-恋爱。在那里问问题五分钟后一刷新回答能有20多个。我经常闲来无事去逛逛,有的人问的问题真的很搞笑。
你还是没有理解这个程序怎么运行的。
你的程序时逐一尝试,只有当前面几种方法都找不到可以落脚的地方的时候,才会使用到不正确的count[8];
所以,并不是一定就错了,而是有了不确定的因素,有错误的可能性(也就是在count[7]之前就搞定了计算,没有遇到过错误的count[8]),但是你换个位置试,如果有一个地方需要回溯,就会使用到count[8]因此就导致了错误
参考技术A 改的你的代码:
#include <stdio.h>
#define N 6
#include <conio.h>
#include <stdlib.h>
/* 棋盘大小 */
int chessbord[N][N];
int Num=0;
void KnightTrav(int i, int x, int y, int chessbord[N][N]);
/* 8种方向 */
static int dx[8] = 2, 1, -1, -2, -2, -1, 1, 2;
static int dy[8] = 1, 2, 2, 1, -1, -2, -2, -1;
main()

int x=0, y=0;

printf("Input the initial position x,y:");
scanf("%d%d", &x, &y);
if ( x<0 || x>N-1 || y<0 || y>N-1) /*输入有效性检查*/

printf("Error Input!\n");
exit(0);


chessbord[x][y] = 1;/* 初始位置 置为1 */

KnightTrav(2, x, y, chessbord); /*正确的调用应该是i+1,所以此处是2,而不是1*/
if(Num==0)
printf("No solution!\n");
else
printf("\nTotal %d Solutions!\n",Num);

return 0;


void KnightTrav(int i, int x, int y, int chessbord[N][N])
/* 递归函数 */
int xx, yy, count = -1;
do
count++;
xx = x + dx[count];
yy = y + dy[count];
if ((xx>=0 && xx<N) && (yy>=0 && yy<N) && chessbord[xx][yy]==0)

chessbord[xx][yy] = i;

if (i < N*N)

KnightTrav(i+1, xx, yy, chessbord);
chessbord[xx][yy] = 0; /*恢复现场*/

else

/*char ch;*/
int ii,jj;
Num++;
printf("\nFind One Solution:\n");
for (ii=0; ii<N; ii++)

for (jj=0; jj<N; jj++)

printf("%4d", chessbord[ii][jj]);

printf("\n");

/*
printf("Continue? (Y/N)\n");
ch=getch();
if(ch=='N'||ch=='n')
exit(0);
*/
chessbord[xx][yy] = 0; /*恢复现场*/


while (count<7); /*注意do-while循环的特点,此处count<8错*/
本回答被提问者采纳
参考技术B 您好!我写了一个此程序,程序如下:
/* knight.c Knight Traversal by Justin Hou (B990614108) 2001/11/23
*
*/
#include <stdio.h>
#define MAX 10

int nRow = 5, nCol = 4; /* count chessboard */
int d[8][2] = 1, 2, 2, 1, 2,-1, 1,-2, /* next step added */
-1,-2, -2,-1, -2, 1, -1, 2;
int flag[MAX][MAX];
int nSolution;

void search(int, int); /* search the way */

void main()

int row, col, i, j;

//clrscr();
//gotoxy(1, 12); /* init the data */
printf("Input the chessboard width and height (nRow, nCol): ");
scanf("%d, %d", &nRow, &nCol);
while (nRow > MAX || nRow < 1 || nCol > MAX || nCol < 1)
printf("error! input again: ");
scanf("%d, %d", &nRow, &nCol);


printf("Input the start point (row, col): ");
scanf("%d, %d", &row, &col);
while (row >= nRow || row < 0 || col >= nCol || col < 0)
printf("error! input again: ");
scanf("%d, %d", &row, &col);
/* init data end */

for (i = 0; i < nRow; i++)
for (j = 0; j < nCol; j++)
//gotoxy(i * 3 + 4, j + 2);
printf(".");


flag[row][col] = 1;
//gotoxy(row*3+4, col+2);
printf("1");
//delay(1000);

search(row, col);
//gotoxy(1, 20);
printf("Solution number is %d", nSolution);

return;


void search(int row, int col)

static int step = 1; /* the step count */
int i, nextRow, nextCol;
for (i = 0; i < 8; i++)
nextRow = row + d[i][0];
nextCol = col + d[i][1];
if (nextRow < nRow && nextRow >= 0
&& nextCol < nCol && nextCol >= 0
&& flag[nextRow][nextCol] == 0)

flag[nextRow][nextCol] = 1;
//gotoxy(nextRow*3+4, nextCol+2);
step++;
printf("%d", step);

if (step < nRow * nCol)
search(nextRow, nextCol);

else
nSolution++;
//gotoxy(1, 20);
printf("n: %d", nSolution);
//delay(50000);


flag[nextRow][nextCol] = 0;
//gotoxy(nextRow*3+4, nextCol+2);
printf(". ");
step--;


return;

大佬帮忙看下这段代码哪里错了。

include file="public/header-simple" /
<body>

<div class="layui-form" lay-filter="layuiadmin-form-admin" id="layuiadmin-form-admin" style="padding: 20px 30px 0 0;">
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-form-mid layui-word-aux">$info['loginname']</div>
<input type="hidden" name="id" class="layui-input" value="$info['id']">
</div>

<div class="layui-form-item">
<label class="layui-form-label">积分数量</label>
<div class="layui-input-inline">
<input type="text" name="point_num" lay-verify="required" placeholder="请输入积分数量" autocomplete="off" class="layui-input">
</div>
</div>

<div class="layui-form-item">
<label class="layui-form-label">价格</label>
<div class="layui-input-inline">
<input type="text" name="money" lay-verify="required" placeholder="请输入价格" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">标注积分对应的价格</div>
</div>

<div class="layui-form-item layui-hide">
<input type="button" lay-submit lay-filter="recharge-admin-back-submit" id="recharge-admin-back-submit" value="确认">
</div>
</div>

include file="public/script" /
<script>
layui.config(
base: '__STATIC__/admin/js/' //静态资源所在路径
).extend(
index: 'lib/index' //主入口模块
).use(['index', 'form'], function()
var $ = layui.$
,form = layui.form ;

//监听提交
form.on('submit(recharge-admin-back-submit)', function(data)
var field = data.field; //获取提交的字段
var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
//提交 Ajax 成功后,关闭当前弹层并重载表格
$.ajax(
url: ":url('Admin/recharge')",
type: "POST",
data: field,
dataType: "json",
success: function(data)
if (data.code == 0)
layer.msg(data.msg);
parent.layui.table.reload('user-admin-table'); //重载表格
parent.layer.close(index); //再执行关闭
else
layer.msg(data.msg);

,
error: function(status)
layer.msg('服务器繁忙,请稍后重试!');

);
//parent.layui.table.reload('adv-list-table'); //重载表格
//parent.layer.close(index); //再执行关闭
);

)
</script>
</body>
</html>

这说明ajax请求报错了,去后台看看控制台的log输出错误 参考技术A 信息错误 可能报错了 参考技术B 报错信息呢?追问

保存提示 :服务器繁忙,请稍后重试

以上是关于骑士游历C语言递归,请大家帮忙看下哪里错了,谢谢的主要内容,如果未能解决你的问题,请参考以下文章

HihoCoder 1504 : 骑士游历 (矩阵乘法)

c语言冒泡排序法代码一直排序错误,有时只能排前两个,不明白原因,请问究竟哪里写错了,谢谢!

C语言程序问题,数组元素无法赋值?请大家帮忙看看

骑士游历问题

初学编程,大家帮忙看下这道c语言题怎么做?万分感谢

c语言 出现空指针赋值怎么回事???请高手帮忙看下。