核心思路
用dfs遍历所有可能的路径,然后在每一轮统计一次步数即可。
算法设计流程
dfs设计细节:
因为是从起点出发遍历所有可能的路径,所有没有明确的返回值,同时不需要回溯,如果把计数器放在dfs参数里,由于回溯计数器最终为0.所有统计步数应该放在dfs外。
此时dfs有两种写法:
写法1:直接用方向数组确定下一个坐标,并在越界和访问过以及数位和都不满足的情况下continue,然后进入下一轮dfs。
写法2:
把越界和访问过以及数位和都不满足的情况下作为返回条件return,
然后写4个方向的dfs。
注意:至于标记走过,统计结果,既可以放在本轮dfs处理,也可以放在选好坐标后的下一轮处理。
代码细节
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int res=0;
static int[] dx=new int[]{-1,1,0,0};
static int[] dy=new int[]{0,0,-1,1};
static int m,n,k;
static boolean[][] vis;
static int[][] map;
static int ans;
// public static void dfs(int x,int y){
// vis[x][y]=true;
// ans++;//步数加1
// for (int i = 0; i < 4; i++) {
// int nx=x+dx[i];
// int ny=y+dy[i];
// if (nx < 0 || ny < 0 || nx >=m || ny >=n||vis[nx][ny]) {
// continue;
// }
// if (get(nx)+get(ny)>k){
// continue;
// }
// dfs(nx,ny);
// }
// }
// public static void dfs(int x,int y){
// if (x<0||y<0||x>=m||y>=n||vis[x][y]){
// return;
// }
// if (get(x)+get(y)>k){
// return;
// }
// vis[x][y]=true;
// ans++;
// dfs(x-1,y);
// dfs(x+1,y);
// dfs(x,y-1);
// dfs(x,y+1);
// }
public static void dfs(int x,int y){
// vis[x][y]=true;
// ans++;//步数加1
for (int i = 0; i < 4; i++) {
int nx=x+dx[i];
int ny=y+dy[i];
if (nx < 0 || ny < 0 || nx >=m || ny >=n||vis[nx][ny]) {
continue;
}
if (get(nx)+get(ny)>k){
continue;
}
vis[nx][ny]=true;
ans++;
dfs(nx,ny);
}
}
public static int get(int x){
int res=0;
while (x>0){
res+=x%10;
x=x/10;
}
return res;
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String[] str=scanner.nextLine().split(" ");
int[] num=new int[str.length];
for (int i = 0; i < str.length; i++) {
num[i]=Integer.parseInt(str[i]);
}
m=num[0];
n=num[1];
k=num[2];
map=new int[m][n];
vis=new boolean[m][n];
for (int i = 0; i < m; i++) {
Arrays.fill(vis[i],false);
}
dfs(0,0);
System.out.println(ans);
}
}