• 考研机试 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的值,然后四个整数表示起始坐标和终止坐标。

    输出描述

    输出最小代价。

    题目链接

    https://www.nowcoder.com/practice/368c98c7bff54a30bba29ae1ba017d55?tpId=40&tqId=21429&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking&tab=answerKey

    二.算法

    题解

    使用深度优先算法(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;
                    }
                }
            }
        }
    }
    努力,向上,自律
  • 相关阅读:
    MFC常见问题解惑
    VS2010之MFC串口通信的编写教程
    Visual C++ 开发心得与调试技巧
    WIN32 DLL中使用MFC
    c++ 类模版、成员函数模版、函数模版 用法
    【学术篇】浅谈各种邻接表
    【模板篇】树状数组们(四)
    【学术篇】网络流24题--飞行员配对方案问题
    【学术篇】网络流24题--骑士共存问题
    【模板篇】树状数组们(三)
  • 原文地址:https://www.cnblogs.com/machi12/p/14561739.html
Copyright © 2020-2023  润新知