黄金矿工(2022-2-5)每日一练

1219. 黄金矿工(2022-2-5)

你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0

为了使收益最大化,矿工需要按以下规则来开采黄金:

  • 每当矿工进入一个单元,就会收集该单元格中的所有黄金。
  • 矿工每次可以从当前位置向上下左右四个方向走。
  • 每个单元格只能被开采(进入)一次。
  • 不得开采(进入)黄金数目为 0 的单元格。
  • 矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。

示例 1:

输入:grid = [[0,6,0],[5,8,7],[0,9,0]]
输出:24
解释:
[[0,6,0],
[5,8,7],
[0,9,0]]
一种收集最多黄金的路线是:9 -> 8 -> 7。

示例 2:

输入:grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]]
输出:28
解释:
[[1,0,7],
[2,0,6],
[3,4,5],
[0,3,0],
[9,0,20]]
一种收集最多黄金的路线是:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7。

提示:

  • 1 <= grid.length, grid[i].length <= 15
  • 0 <= grid[i][j] <= 100
  • 最多 25 个单元格中有黄金。

解题思路

典型的dfs题,递归调用,(回溯求值),此题的写法近乎模版,得牢记。写法和bfs差不多,区别在于向每个方向移动时,继续递归调用dfs,就可以达成深度搜索

另外由于起点存在很多个,如果遍历所有矿点作为起点,那么时间复杂度就会有点高,我们可以稍微优化一下,筛选一下起点。如果该矿点的上下方向(或者左右方向)有矿,那么它必定是路上的点,不是最佳起点,不进行dfs

var getMaximumGold = function(grid) {
    let disrection = [[0,1],[0,-1],[1,0],[-1,0]]
    let m = grid.length, n =grid[0].length, res = 0
    function dfs (x,y,sum){
        sum += grid[x][y]
    		res = Math.max(res,sum)
        let temp = grid[x][y]
        grid[x][y] = 0
        for(let dir of disrection){
           let [i,j] = [x + dir[0], y + dir[1]]
           if(i >= 0 && j >= 0  && i < m && j < n && grid[i][j] > 0){
               dfs(i,j,sum)
           }
       	}
    		grid[x][y] = temp
        return sum
    }
    for(let i = 0; i < m; i++){
        for(let j = 0; j < n; j++){
            if(grid[i][j] > 0)
            dfs(i,j,0)
          // 起点小优化
//           if (grid[i][j] > 0
//               && !((i-1 > 0 && grid[i - 1][j] 
//               && i+1 < m &&  grid[i + 1][j]) 
//            	 || (j-1 > 0 && grid[i][j - 1] 
//               && j+1 < n && grid[i][j + 1]))) {dfs(i, j, 0);}
        }
    }
    return res
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的黄金矿工游戏的HTML5代码示例: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>黄金矿工游戏</title> <style> canvas { border: solid 1px #000000; } </style> </head> <body> <canvas id="canvas" width="800" height="600"></canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var gold = new Image(); gold.src = "https://i.imgur.com/1zUfJ7L.png"; var miner = new Image(); miner.src = "https://i.imgur.com/sjQGZKj.png"; var score = 0; var time = 60; var timer; function drawGold() { var x = Math.random() * (canvas.width - 50); var y = Math.random() * (canvas.height - 50); ctx.drawImage(gold, x, y, 50, 50); } function drawMiner(x, y) { ctx.drawImage(miner, x, y, 50, 50); } function updateTime() { time--; if (time < 0) { clearInterval(timer); alert("时间到,游戏结束!得分:" + score); } else { document.getElementById("time").innerHTML = "时间:" + time; } } function startGame() { score = 0; time = 60; clearInterval(timer); timer = setInterval(updateTime, 1000); document.getElementById("score").innerHTML = "得分:" + score; document.getElementById("time").innerHTML = "时间:" + time; ctx.clearRect(0, 0, canvas.width, canvas.height); drawMiner(canvas.width / 2 - 25, canvas.height / 2 - 25); for (var i = 0; i < 10; i++) { drawGold(); } } function checkCollision(x1, y1, w1, h1, x2, y2, w2, h2) { return x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2; } canvas.addEventListener("mousemove", function(event) { var x = event.clientX - canvas.offsetLeft - 25; var y = event.clientY - canvas.offsetTop - 25; ctx.clearRect(0, 0, canvas.width, canvas.height); drawMiner(x, y); for (var i = 0; i < canvas.children.length; i++) { if (canvas.children[i].tagName == "IMG") { var goldX = canvas.children[i].offsetLeft; var goldY = canvas.children[i].offsetTop; if (checkCollision(x, y, 50, 50, goldX, goldY, 50, 50)) { score++; canvas.removeChild(canvas.children[i]); drawGold(); document.getElementById("score").innerHTML = "得分:" + score; } } } }); startGame(); </script> <div> <button onclick="startGame()">重新开始</button> <span id="score"></span> <span id="time"></span> </div> </body> </html> ``` 这个游戏包含一个画布和一些简单的JavaScript代码。游戏开始时,你将看到一个矿工在画布的中心,以及一些金子随机分布在画布上。你可以通过移动鼠标来控制矿工的位置。当矿工与金子碰撞时,你将得到一分。游戏时间为60秒,时间结束后将显示得分。你可以通过点击“重新开始”按钮来重新开始游戏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值