2019阿里应届内推编程题

先挂题目

————————————————————————————————————————————————————————

光明小学的小朋友们要举行一年一度的接力跑大赛了,但是小朋友们却遇到了一个难题:设计接力跑大赛的线路,你能帮助他们完成这项工作么?
光明小学可以抽象成一张有N个节点的图,每两点间都有一条道路相连。光明小学的每个班都有M个学生,所以你要为他们设计出一条恰好经过M条边的路径。
光明小学的小朋友们希望全盘考虑所有的因素,所以你需要把任意两点间经过M条边的最短路径的距离输出出来以供参考。

你需要设计这样一个函数:
res[][] Solve( N, M, map[][]);
注意:map必然是N * N的二维数组,且map[i][j] == map[j][i],map[i][i] == 0,-1e8 <= map[i][j] <= 1e8。(道路全部是无向边,无自环)2 <= N <= 100, 2 <= M <= 1e6。要求时间复杂度控制在O(N^3*log(M))。

map数组表示了一张稠密图,其中任意两个不同节点i,j间都有一条边,边的长度为map[i][j]。N表示其中的节点数。
你要返回的数组也必然是一个N * N的二维数组,表示从i出发走到j,经过M条边的最短路径
你的路径中应考虑包含重复边的情况。

——————————————————————————————————————————————————————

题目特别长,加上有点紧张,光是读题目就花了很久的时间。泪流满面谨以此题纪念即将三挂阿里的我。

——————————————————————————————————————————————————————

思路有点类似与求和问题,牛客网上的一道题目https://www.nowcoder.com/practice/11cc498832db489786f8a03c3b67d02c?tpId=85&&tqId=29869&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking但不完全一样。有兴趣可以做做。

先挂代码吧。。。

package ali;

import java.util.Scanner;

public class zhaolu {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int m = input.nextInt();
		long[][] map = new long[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				map[i][j] = input.nextLong();
			}
		}
		long[][] res = new long[n][n];
		for (int i = 0; i < res.length; i++) {
			for (int j = 0; j < res.length; j++) {
				res[i][j] = Integer.MAX_VALUE;
			}
		}
		for (int i = 0; i < n; i++) {
			int nowrow = i;
			int nowcol = i;
			int distance = 0;
			solve(nowcol, m, map, res, distance, nowrow);
		}
		for (int i = 0; i < res.length; i++) {
			for (int j = 0; j < res.length; j++) {
				System.out.print(res[i][j] + " ");
			}
			System.out.println();
		}

	}

	public static void solve(int nowcol, int m, long[][] map, long[][] res, long distance, int nowrow) {
		if (m == 0) {
			if (distance < res[nowrow][nowcol]) {
				res[nowrow][nowcol] = distance;
				return;
			}
			return;
		}
		for (int nextcol = 0; nextcol < map[0].length; nextcol++) {
			if (nowcol != nextcol) {
				solve(nextcol, m - 1, map, res, distance + map[nowcol][nextcol], nowrow);
			}
		}
		return;
	}

}

其实就一个solve函数。

nowrow,记录当前是哪一个出发点,每一行可以对应一个出发点。

nowcol,记录当前走到了哪一个节点。

m,用来记录还需要走多少步。

res,记录最短路径的矩阵

distance,表示当前走的距离

跳出递归的条件是,m==0也就是走完了规定的步数,更改记录的条件是,当前这种走法比以前的走法都要短。

递归过程中下一步是不能与当前位置重合的。

突然发现没什么好讲的了……这题思路并不难,就是参数比较多,处理起来容易出错……

祝大家好运~我再去哭一会儿……

猜你喜欢

转载自blog.csdn.net/qq_32742009/article/details/81182933