C语言递归实现骑士有限步数可达位置标记异常问题排查
C语言递归实现骑士有限步数可达位置标记异常问题排查
嘿,我来帮你排查这个骑士移动标记的问题!你的递归思路方向是对的,但核心问题出在访问位置时的返回逻辑上,咱们慢慢捋清楚:
问题根源:过早终止递归路径
你看你写的whiteMove函数里,有一段逻辑是:如果当前位置已经被标记为1,就直接return终止递归。这个逻辑在步数限制小的时候没问题,但步数超过2就会出问题——因为某个位置可能被更少步数的路径先标记了,当后续用更多步数的路径走到这里时,你直接终止了递归,导致从这个位置出发的后续移动(也就是刚好达到最大步数的那些位置)根本没机会被标记。
举个你提到的例子:map[6][2]在步数限制为2时就被标记成1了。当步数限制为3时,假设有一条路径用3步走到map[6][2],这时候你的代码发现它已经是1,直接return,没有继续递归它的8个方向,那map[5][0]和map[7][4]这些需要从map[6][2]再走一步(也就是总共3步)才能到达的位置,就永远不会被标记了。
修复方案:调整标记与递归逻辑
我们需要的是标记所有最多N步能到达的位置,不管这个位置是1步、2步还是N步走到的。所以即使某个位置已经被标记,只要当前剩余步数还没耗尽,我们依然要继续递归它的下一步,这样才能覆盖那些需要用满N步才能到达的位置。
修改后的whiteMove函数如下:
void whiteMove(int wx, int wy,int map[8][8], int limit){ // 边界越界或者剩余步数为0,直接返回 if(wx<0||wy<0||wx>7||wy>7||limit==0){ return; } // 只要还能走,先把当前位置标记为1(重复标记不影响结果) map[wy][wx] = 1; // 遍历骑士的8个可能移动方向,剩余步数减1继续递归 for(int i=0;i<8;i++){ whiteMove(wx+xpos[i],wy+ypos[i],map,limit-1); } }
为什么这样改就对了?
- 去掉了“位置已标记就返回”的逻辑,只要剩余步数>0,不管位置有没有被标记,都会继续递归下一步。
- 标记操作
map[wy][wx] = 1是幂等的——就算重复设置成1,结果还是1,不会影响最终的地图状态。 - 这样所有最多N步能到达的位置,不管是通过哪条路径到达的,都会被正确标记,包括那些需要用满N步才能走到的位置。
你可以试试修改后的代码,输入步数限制3时,map[5][0]和map[7][4]这些位置应该就能被正确标记为1了。
备注:内容来源于stack exchange,提问作者penguinn
相关产品推荐
相关产品推荐

