考研机试 98.棋盘游戏
时间:2021/03/20
一.题目描述
有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径: 1、只能沿上下左右四个方向移动 2、总代价是没走一步的代价之和 3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积 4、初始状态为1 每走一步,状态按如下公式变化:(走这步的代价%4)+1。
输入描述
每组数据一开始为6*6的矩阵,矩阵的值为大于等于1小于等于10的值,然后四个整数表示起始坐标和终止坐标。
输出描述
输出最小代价。
题目链接
二.算法
题解
使用深度优先算法(bfs)和剪枝来寻找图中的最小代价路径。开始看到寻找最短路径想用bfs,但是发现由于每步的代价不一样,所以最先找到的路径并不一定是代价最小的路径,所以只能使用dfs对全局进行搜索,主要要使用剪枝来避免不必要的搜索。
代码
import java.util.Scanner; public class Main{ public static int endX, endY; //终点坐标 public static boolean[][] flag = new boolean[6][6]; public static int[][] map = new int[6][6]; public static int minCost = Integer.MAX_VALUE; //最小代价 public static int[][] dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; public static void main(String[] args){ Scanner in = new Scanner(System.in); //读取输入 for(int i = 0; i < 6; i++){ for(int j = 0; j < 6; j++){ map[i][j] = in.nextInt(); } } //起点坐标 int startX = in.nextInt(); int startY = in.nextInt(); //终点坐标 endX = in.nextInt(); endY = in.nextInt(); flag[startX][startY] = true; dfs(startX, startY, 1, 0); System.out.println(minCost); } //使用深度优先算法求最小代价 public static void dfs(int startX, int startY, int status, int cost){ //剪枝 if(cost < minCost){ if(startX == endX && startY == endY){ minCost = cost; } for(int i = 0; i < 4; i++){ int x = startX + dir[i][0]; int y = startY + dir[i][1]; if(x >= 0 && x < 6 && y >= 0 && y <6 && !flag[x][y]){ int newCost = map[x][y] * status; int newStatus = (newCost % 4) + 1; flag[x][y] = true; dfs(x, y, newStatus, cost + newCost); flag[x][y] = false; }else{ continue; } } } } }
努力,向上,自律