华为OD-2024年E卷-智能驾驶[200分]( Java | Python3 | C++ | C语言 | JsNode | Go)实现100%通过率

题目描述

有一辆汽车需要从m*n的地图的左上角(起点)开往地图的右下角(终点),去往每一个地区都需要消耗一定的油量,加油站可进行加油
请你计算汽车确保从起点到达终点时所需的最少初始油量说明:
(1)智能汽车可以上、下、左、右四个方向移动(2)地图中的数字取值是0或-1或正整数:
-1:表示加油站,可以加满油,汽车的油箱容量最大为100;0:表示这个地区是障碍物,汽车不能通过;正整数:表示汽车走过这个地区的耗油量
(3)如果汽车无论如何都无法到达终点,则返回-1


输入描述
第一行为两个数字,M、N,表示地图的大小为M*N
后面是一个M*N的矩阵,其中的值是0或-1或正整数,加油站的总数不超过200个


输出描述
如果汽车无论如何都无法到达终点,则返回-1。如果汽车可以到达终点,则返回最少的初始油量。


补充说明
0<M,N<=200

示例1  
输入   
2,2

10,20

30,40
输出 
70
说明
行走路线为:右->下


示例2
输入
4,4
10,30,30,20

30,30,-1,10

0,20,20,40

10,-1,30,40
输出 
70
说明
行走路线为:右->右->下->下->下->右

示例3
输入 
4,5
10,0,30,-1,10
30,0,20,0,20
10,0,10,0,30
10,-1,30,0,10
输出
60
说明
行走路线为:下->下->下->右->右->上->上->上->右->右->下->下->下


示例4
输入
4,4
10,30,30,20

30,30,20,10

10,20,10,40

10,20,30,40
输出 
-1

说明
无论如何都无法到达终点

Java 

import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
    // 定义一个极大值用来表示无限大
    public static int inf = (int) 1e9;
    // 地图的行数和列数
    public static int n, m;
    // 地图数组
    public static int[][] g;
    // 表示四个方向的移动
    public static int[][] nxt = new int[][] { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
    // 表示是否已经访问过的位置
    public static Boolean[][][] f;
    // 优先队列用于广度优先搜索
    public static PriorityQueue<int[]> pq;

    // 检查给定的初始油量mid是否能达到终点
    public static boolean check(int mid) {
        // 如果起点的油耗量大于初始油量,则返回false
        if (g[0][0] > mid) {
            return false;
        }
        // 优先队列用于存储当前路径的油耗情况
        pq = new PriorityQueue<>((x, y) -> {
            return x[0] - y[0];
        });
        // 初始化访问数组,用于记录在特定油量下,某位置是否被访问过
        f = new Boolean[n][m][101];
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                for (int k = 0; k < 101; ++k) {
                    f[i][j][k] = false;
                }
            }
        }
        // 计算初始剩余油量
        int st = mid - g[0][0];
        // 将起点加入优先队列
        pq.add(new int[] { g[0][0], st, 0, 0 });
        f[0][0][st] = true;
        // 开始广度优先搜索
        while (pq.size() > 0) {
            int[] tp = pq.poll();
            int val = tp[1], x = tp[2], y = tp[3];
            // 如果已经到达终点,返回true
            if (x == n - 1 && y == m - 1) {
                return true;
            }
            // 遍历四个方向
            for (int k = 0; k < 4; k++) {
                int nx = x + nxt[k][0], ny = y + nxt[k][1];
                // 检查新的位置是否在地图范围内并且不是障碍物
                if (nx < 0 || nx >= n || ny < 0 || ny >= m || g[nx][ny] == 0) {
                    continue;
                }
                int dval = val - g[nx][ny];
                // 如果当前油量可以到达新位置
                if (dval >= 0) {
                    int need = tp[0] + g[nx][ny];
                    // 如果新位置是加油站,重置油量
                    if (g[nx][ny] == -1) {
                        need += 1;
                        dval = 100;
                    }
                    // 如果新位置以及剩余油量组合没有被访问过,加入优先队列
                    if (!f[nx][ny][dval]) {
                        pq.add(new int[] { need, dval, nx, ny });
                        f[nx][ny][dval] = true;
                    }
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 读取地图的行数和列数
        String[] tmp = sc.nextLine().split(",");
        n = Integer.parseInt(tmp[0]);
        m = Integer.parseInt(tmp[1]);
        g = new int[n][m];
        // 读取地图数据
        for (int i = 0; i < n; i++) {
            tmp = sc.nextLine().split(",");
            for (int j = 0; j < m; j++) {
                g[i][j] = Integer.parseInt(tmp[j]);
            }
            // 起点是障碍物,直接返回-1
            if (g[0][0] == 0) {
                System.out.println(-1);
                return;
            }
        }
        // 二分搜索初始油量
        int left = 0, right = 100;
        int res = inf;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (check(mid)) {
                right = mid - 1;
                res = mid;
            } else {
                left = mid + 1;
            }
        }
        // 如果起点是加油站,且找到了结果,输出0
        if (g[0][0] == -1 && res != inf) {
            System.out.println(0);
        } else {
            // 输出结果
            if (res == inf) {
                System.out.println(-1);
            } else {
                System.out.println(res);
            }
        }
    }
}

Python3

import heapq
 
inf = int(1e9)
nxt = [(0, 1), (1, 0), (0, -1), (-1, 0)]
 
def check(g, n, m, mid):
    if g[0][0] > mid:
        return False
    pq = []
    f = [[[False] * 101 for _ in range(m)] for _ in range(n)]
    st = mid - g[0][0]
    heapq.heappush(pq, (g[0][0], st, 0, 0))
    f[0][0][st] = True
    while pq:
        val, st, x, y = heapq.heappop(pq)
        if x == n - 1 and y == m - 1:
            return True
        for dx, dy in nxt:
            nx, ny = x + dx, y + dy
            if 0 <= nx < n and 0 <= ny < m and g[nx][ny] != 0:
                dval = st - g[nx][ny]
                if dval >= 0:
                    need = val + g[nx][ny]
                    if g[nx][ny] == -1:
                        need += 1
                        dval = 100
                    if not f[nx][ny][dval]:
                        heapq.heappush(pq, (need, dval, nx, ny))
                        f[nx][ny][dval] = True
    return False
 
def main():
    data = input().split(',')
    n, m = int(data[0]), int(data[1])
    g = []
    idx = 2
    for i in range(n):
        row = list(map(int,input().split(',')))
        g.append(row)
    if g[0][0] == 0:
        print(-1)
        return
    left, right = 0, 100
    res = inf
    while left <= right:
        mid = (left + right) // 2
        if check(g, n, m, mid):
            right = mid - 1
            res = mid
        else:
            left = mid + 1
    if g[0][0] == -1 and res != inf:
        print(0)
    elif res == inf:
        print(-1)
    else:
        print(res)
 
if __name__ == '__main__':
    main()

C++ 

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
 
const int inf = 1e9;
int n, m;
vector<vector<int>> g;
vector<vector<vector<bool>>> f;
int nxt[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
 
bool check(int mid) {
    if (g[0][0] > mid) return false;
    priority_queue<vector<int>, vector<vector<int>>, greater<>> pq;
    f.assign(n, vector<vector<bool>>(m, vector<bool>(101, false)));
    int st = mid - g[0][0];
    pq.push({g[0][0], st, 0, 0});
    f[0][0][st] = true;
    while (!pq.empty()) {
        auto tp = pq.top(); pq.pop();
        int val = tp[1], x = tp[2], y = tp[3];
        if (x == n - 1 && y == m - 1) return true;
        for (int k = 0; k < 4; k++) {
            int nx = x + nxt[k][0], ny = y + nxt[k][1];
            if (nx < 0 || nx >= n || ny < 0 || ny >= m || g[nx][ny] == 0) continue;
            int dval = val - g[nx][ny];
            if (dval >= 0) {
                int need = tp[0] + g[nx][ny];
                if (g[nx][ny] == -1) {
                    need += 1;
                    dval = 100;
                }
                if (!f[nx][ny][dval]) {
                    pq.push({need, dval, nx, ny});
                    f[nx][ny][dval] = true;
                }
            }
        }
    }
    return false;
}
vector<int> split(string& s){
    int x=0,f=1;
    vector<int> res;
    for(auto&i:s){
        if(i==','){
            res.push_back(x*f);
            x=0;
            f=1;
        }else if(i=='-'){
            f=-1;
        }else{
            x=x*10+i-'0';
        }
    }
    res.push_back(x*f);
    return res;
}
int main() {
    string tmp;
    getline(cin,tmp);
    vector<int> v=split(tmp);
    n=v[0];
    m=v[1];
    for (int i = 0; i < n; i++){
        getline(cin,tmp);
        v=split(tmp);
        g.push_back(v);
    }
    if (g[0][0] == 0) {
        cout << -1 << endl;
        return 0;
    }
    int left = 0, right = 100, res = inf;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (check(mid)) {
            right = mid - 1;
            res = mid;
        } else {
            left = mid + 1;
        }
    }
    if (g[0][0] == -1 && res != inf) {
        cout << 0 << endl;
    } else {
        cout << (res == inf ? -1 : res) << endl;
    }
    return 0;
}

C语言 

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
 
#define INF 1000000000
 
struct Node {
    int cost;
    int fuel;
    int x;
    int y;
};
 
int n, m;
int g[100][100];
bool f[100][100][101];
 
int dir[4][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };
 
bool check(int mid) {
    if (g[0][0] > mid) return false;
 
    struct Node pq[1000000];
    int pq_size = 0;
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            for (int k = 0; k <= 100; k++)
                f[i][j][k] = false;
 
    int startFuel = mid - g[0][0];
    pq[pq_size++] = (struct Node) {
        g[0][0], startFuel, 0, 0
    };
    f[0][0][startFuel] = true;
 
    while (pq_size > 0) {
        struct Node node = pq[--pq_size];
        int cost = node.cost;
        int fuel = node.fuel;
        int x = node.x;
        int y = node.y;
 
        if (x == n - 1 && y == m - 1) return true;
 
        for (int k = 0; k < 4; k++) {
            int nx = x + dir[k][0];
            int ny = y + dir[k][1];
 
            if (nx < 0 || nx >= n || ny < 0 || ny >= m || g[nx][ny] == 0) continue;
 
            int remainingFuel = fuel - g[nx][ny];
            if (remainingFuel >= 0) {
                int newCost = cost + g[nx][ny];
                if (g[nx][ny] == -1) {
                    newCost++;
                    remainingFuel = 100;
                }
                if (!f[nx][ny][remainingFuel]) {
                    pq[pq_size++] = (struct Node) {
                        newCost, remainingFuel, nx, ny
                    };
                    f[nx][ny][remainingFuel] = true;
                }
            }
        }
    }
 
    return false;
}
char tmp[100005];
int main() {
    scanf("%d,%d", &n, &m);
    gets(tmp);
    for (int i = 0; i < n; i++) {
        gets(tmp);
        int sz=strlen(tmp);
        int p=0;
        int x=0;
        int f=1;
        for(int j=0;j<sz;++j){
            if(tmp[j]=='-'){
                f=-1;
            }else if(tmp[j]==','){
                g[i][p]=x*f;
                p+=1;
                x=0;
                f=1;
            }else{
                x=x*10+tmp[j]-'0';
            }
        }
        g[i][p]=x*f;
    }
 
    if (g[0][0] == 0) {
        printf("-1\n");
        return 0;
    }
 
    int left = 0, right = 100;
    int res = INF;
 
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (check(mid)) {
            right = mid - 1;
            res = mid;
        } else {
            left = mid + 1;
        }
    }
 
    if (g[0][0] == -1 && res != INF) {
        printf("0\n");
    } else {
        printf("%d\n", res == INF ? -1 : res);
    }
 
    return 0;
}

JsNode 

const rl = require("readline").createInterface({ input: process.stdin, output: process.stdout, });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function () {

    const inf = 1e9;
    const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
    let n, m, g=[], f;
    let pq = [];

    function check(mid) {
        if (g[0][0] > mid) return false;
        pq = [];
        f = Array.from({ length: n }, () => Array.from({ length: m }, () => Array(101).fill(false)));
        let st = mid - g[0][0];
        pq.push([g[0][0], st, 0, 0]);
        f[0][0][st] = true;

        while (pq.length) {
            pq.sort((a, b) => a[0] - b[0]);
            let [val, st, x, y] = pq.pop();

            if (x === n - 1 && y === m - 1) return true;

            for (let [dx, dy] of directions) {
                let nx = x + dx, ny = y + dy;

                if (nx < 0 || nx >= n || ny < 0 || ny >= m || g[nx][ny] === 0) continue;

                let dval = st - g[nx][ny];
                if (dval >= 0) {
                    let need = val + g[nx][ny];
                    if (g[nx][ny] === -1) {
                        need += 1;
                        dval = 100;
                    }
                    if (!f[nx][ny][dval]) {
                        pq.push([need, dval, nx, ny]);
                        f[nx][ny][dval] = true;
                    }
                }
            }
        }
        return false;
    }
    let tmp=(await readline()).split(",").map(Number);
    n=tmp[0];
    m=tmp[1];
    
    for (let i = 0; i < n; i++) {
        let row=(await readline()).split(",").map(Number);
        g.push(row);
    }
    
    if (g[0][0] === 0) {
        console.log(-1);
        return;
    }
    
    let left = 0, right = 100;
    let res = inf;
    
    while (left <= right) {
        let mid = Math.floor((left + right) / 2);
        if (check(mid)) {
            right = mid - 1;
            res = mid;
        } else {
            left = mid + 1;
        }
    }
    
    if (g[0][0] === -1 && res !== inf) {
        console.log(0);
    } else {
        console.log(res === inf ? -1 : res);
    }
    
}()

 

Go

package main
 
import (
	"container/heap"
	"fmt"
    "strconv"
    "strings"
)
 
const inf = 1e9
 
type Node struct {
	cost int
	fuel int
	x    int
	y    int
}
 
type PriorityQueue []*Node
 
func (pq PriorityQueue) Len() int { return len(pq) }
 
func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].cost < pq[j].cost
}
 
func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
}
 
func (pq *PriorityQueue) Push(x interface{}) {
	item := x.(*Node)
	*pq = append(*pq, item)
}
 
func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	*pq = old[0 : n-1]
	return item
}
 
var (
	dirs = [][2]int{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
	n, m int
	g    [][]int
	f    [][][]bool
)
 
func check(mid int) bool {
	if g[0][0] > mid {
		return false
	}
	pq := &PriorityQueue{}
	heap.Init(pq)
	f = make([][][]bool, n)
	for i := 0; i < n; i++ {
		f[i] = make([][]bool, m)
		for j := 0; j < m; j++ {
			f[i][j] = make([]bool, 101)
		}
	}
	st := mid - g[0][0]
	heap.Push(pq, &Node{g[0][0], st, 0, 0})
	f[0][0][st] = true
	for pq.Len() > 0 {
		tp := heap.Pop(pq).(*Node)
		val, st, x, y := tp.cost, tp.fuel, tp.x, tp.y
		if x == n-1 && y == m-1 {
			return true
		}
		for _, dir := range dirs {
			nx, ny := x+dir[0], y+dir[1]
			if nx < 0 || nx >= n || ny < 0 || ny >= m || g[nx][ny] == 0 {
				continue
			}
			dval := st - g[nx][ny]
			if dval >= 0 {
				need := val + g[nx][ny]
				if g[nx][ny] == -1 {
					need++
					dval = 100
				}
				if !f[nx][ny][dval] {
					heap.Push(pq, &Node{need, dval, nx, ny})
					f[nx][ny][dval] = true
				}
			}
		}
	}
	return false
}
 
func main() {
    var input string
    fmt.Scan(&input)
    strSlice := strings.Split(input, ",")
    intSlice := make([]int, len(strSlice))
    for i, s := range strSlice {
        num, err := strconv.Atoi(s)
        if err!= nil {
            return
        }
        intSlice[i] = num
    }
    n=intSlice[0]
    m=intSlice[1]
    g = make([][]int, n)
	for i := 0; i < n; i++ {
		g[i] = make([]int, m)
	    fmt.Scanln(&input)
        strSlice := strings.Split(input, ",")
        for j, s := range strSlice {
            num, err := strconv.Atoi(s)
            if err!= nil {
                return
            }
            g[i][j] = num
        }
	}
	if g[0][0] == 0 {
		fmt.Println(-1)
		return
	}
	left, right, res := 0, 100, 999999
	for left <= right {
        mid := int((left + right) / 2)
		if check(mid) {
			right = mid - 1
			res = mid
		} else {
			left = mid + 1
		}
	}
	if g[0][0] == -1 && res != 999999 {
		fmt.Println(0)
	} else {
		fmt.Println(res)
	}
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值