T1、亲子游戏:

题目:

        宝宝和妈妈参加亲子游戏,在一个二维矩阵(N*N)的格子地图上,宝宝和妈妈抽签决定各自的位置,地图上每个格子有不同的糖果数量,部分格子有障碍物。

        游戏规则是妈妈必须在最短的时间(每个单位时间只能走一步)到达宝宝的位置,路上的所有糖果都可以拿走,不能走障碍物的格子,只能上下左右走。

        请问妈妈在最短到达宝宝位置的时间内最多拿到多少糖果(优先考虑最短时间到达的情况下尽可能多拿糖果)。

思路:

/**
 * 1、先创建一个含糖果点类(坐标、妈妈到达步数step、已获取的糖果数)
 * 2、创建一个位置数组points,并进行初始化
 * 3、初始化妈妈的步数,并将妈妈的点对象加入队列
 * 4、循环遍历队列,直到队列为空;从上、下、左、右(顺序不固定)分别找儿子的位置,如果妈妈走的下一个位置,与那个位置的路径相比更短,那就说明此时妈妈走的就是更优解,所以更新那个位置的步数和糖果数;如果路径相等,则取较大的糖果数对应的位置。并将下一个点位置放入队列中,继续扩张广度遍历。
 * 5、如果妈妈找到儿子的位置,直接返回糖果数;否则返回-1,没有找到。
 */

题解: 

class CandyPoint{
    int x,y,candy,step;
    public CandyPoint(int x, int y, int candy, int step){
        this.x = x;
        this.y = y;
        this.candy = candy;
        this.step = step;
    }
}

public class T01CandyGame {
    //定义一个上、下、左、右位置的int[4][2]数组
    public int[][] DIRECTIONS = {{0,1},{0,-1},{-1,0},{1,0}};

    public int minPathAndMaxCandy(int[][] grid, CandyPoint mon, CandyPoint kid){
        int n = grid.length;

        CandyPoint[][] points = new CandyPoint[n][n];

        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                points[i][j] = new CandyPoint(i,j,grid[i][j],Integer.MAX_VALUE);
            }
        }

        //需要一个队列记录需访问的位置
        Queue<CandyPoint> queue = new PriorityQueue<>(Comparator.comparingInt(a->a.candy));

        //初始化,从妈妈位置开始遍历
        mon.step=0;
        queue.offer(mon);

        //广度优先遍历糖果数组
        while(!queue.isEmpty()){
            CandyPoint current = queue.poll();

            //妈妈找到儿子位置
            if(current.x==kid.x && current.y==kid.y){
                return current.candy;
            }

            for(int[] direction:DIRECTIONS){
                int newX = current.x + direction[0];
                int newY = current.y + direction[1];

                if(newX>=0 && newX<n && newY >=0 && newY<n && grid[newX][newY]!=-1){
                    CandyPoint next = points[newX][newY];

                    //妈妈走到下一步,步数+1,糖果数累加
                    int newStep = current.step+1;
                    int newCandy = current.candy + grid[newX][newY];    //注意这里不能用next.candy,points数组中元素会重复访问,且元素的candy会叠加

                    //取较短的路径,或者路径相同,糖果数较多的位置
                    if(newStep<next.step || newStep==next.step && newCandy>next.candy){
                        next.candy = newCandy;
                        next.step = newStep;
                        queue.offer(next);
                    }
                }
            }
        }
        return -1;
    }
}

马上要参加机考了,欢迎评论区交流,欢迎评论区提供其它解题思路(或代码)。

参考链接:题一:亲子游戏_亲子游戏java-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值