算法-在规定的步骤内有多少种方式走出边界

本文探讨了一只地鼠如何在限定步数内从矩形田地中逃出的问题,通过递归回溯算法提供了两种解决方案:一种允许路径重复,另一种则避免路径重复。详细介绍了算法的实现过程,并附带了Java代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

有一只地鼠不小心跑进了一个m*n的矩形田地里,假设地鼠在这块田地的初始位置为(x,y),并且每次只能向相邻的上下左右四个方向移动一步,那么在最多移动K次的情况下,有多少条路径可以逃出这片田地(一旦出去田地的边界就不能再往回走)?

输入描述:

输入数据包括五个参数:m,n,x,y,K
其中m和n的范围均为是[1,10],K的范围是[0,10]。
0<=x<m,0<=y<n。

输出描述:

输出成功逃跑的路径数量。

分析:一看题目就是需要采用穷举的方式(采用回溯的方式),一涉及的穷举,我首先想到的是采用递归的方式来进行求解。

本题有意思的是没有限制走过的路径不能重复,下面给出允许路径重复的解答和不允许路径重复的解答。对于允许重复,你就随便走,分上下左右四个方向遍历即可;而对于不允许重复的走法,需要对于走过的路径用一个数组记录下来。当找到对应的解或者移动的步骤已经达到K时,需要考虑回溯,既然回溯,就需要将当前走过的标识重新擦除,因为其他走法也可能走到此方格。

允许方格重复的走法:

import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int m = Integer.valueOf(br.readLine());
        int n = Integer.valueOf(br.readLine());
        int x = Integer.valueOf(br.readLine());
        int y = Integer.valueOf(br.readLine());
        int k = Integer.valueOf(br.readLine());
        System.out.println(recursive(m, n, x, y, k));
    }
    
    public static int recursive(int m, int n, int x, int y, int remain) {
        if(remain < 0) {
            return 0;
        }
        if(x >= m || x < 0) {
            return 1;
        }
        if(y >= n || y < 0) {
            return 1;
        }
        return recursive(m, n, x + 1, y, remain - 1) + 
            recursive(m, n, x - 1, y, remain - 1) +
            recursive(m, n, x, y + 1, remain - 1) +
            recursive(m, n, x, y - 1, remain - 1);
    }
}

路径上的方格不能重复的走法:

import java.io.BufferedReader;
import java.io.InputStreamReader;


public class SolutionTest {


    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int m = Integer.valueOf(br.readLine());
        int n = Integer.valueOf(br.readLine());
        int x = Integer.valueOf(br.readLine());
        int y = Integer.valueOf(br.readLine());
        int k = Integer.valueOf(br.readLine());
        boolean[][] isWalk = new boolean[m][n];
        isWalk[x][y] = true;
        System.out.println(recursive(m, n, x, y, k,  isWalk));
    }

    private static int recursive(int m, int n, int x, int y, int k, boolean[][] isWalk) {
        if(k == 0) {
            return 0;
        }
        int right = 0;
        int top = 0;
        int left = 0;
        int bottom = 0;
        if(y == n - 1) {
            right = 1;
        }else if(!isWalk[x][y + 1]) {
            isWalk[x][y + 1] = true;
            right = recursive(m, n, x, y + 1, k - 1, isWalk);
            isWalk[x][y + 1] = false;
        }
        if(x == 0) {
            top = 1;
        }else if(!isWalk[x - 1][y]) {
            isWalk[x - 1][y] = true;
            top = recursive(m, n, x -1, y, k - 1, isWalk);
            isWalk[x - 1][y] = false;
        }
        if(y == 0) {
            left = 1;
        }else if(!isWalk[x][y - 1]) {
            isWalk[x][y -1] = true;
            left = recursive(m, n, x, y - 1, k - 1, isWalk);
            isWalk[x][y - 1]=  false;
        }
        if(x == m - 1) {
            bottom = 1;
        }else if(!isWalk[x + 1][y]) {
            isWalk[x + 1][y] = true;
            bottom = recursive(m, n, x + 1, y, k -1, isWalk);
            isWalk[x + 1][y] = false;

        }
        return right + top + left + bottom;
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值