华为2019秋招笔试Java实现(3)
笔试日期2019年8月14日
第三题(300分)
题目描述
有一款社交软件APP,假设注册用户m人(0<m<50),用户编号为0~m-1,用r[i,j]表示用户i和用户j好友关系(r[i][j]=0表示i和j不是好友,r[i][j]=1~9代表是好友且数值代表熟悉程度,数值越打代表越熟悉,其中r[i][j]=r[j][i],0<=i,j<=m-1),试编制程序,输出某个特定用户i的n度好友(1度好友代表直接好友,2度好友代表好友的好友,一次类推1<=n<=10),并按推荐值降序输出好友列表(推荐值相同的好友,按好友编号升序,其中推荐值是指关系熟悉度之和,比如用户i和j是好友且熟悉度r[i][j]=4,j和k是好友且熟悉度r[j][k]=6,且i和k不是好友即r[i][j]=0,则用户k是用户i的2度好友且推荐值为r[i][j]+r[j][k]=10),如果此用户i没有n度好友输出-1。
输入描述
输入一个整数T,表示有T组测试数据(0<T<100)。
对于每组测试数据输入两行,
第1行 输入3个整型数m,i,n分别代表用户数m,某个用户编号i,n度好友,即代表本组测试需要输出用户i的n度好友,
第2行 输入1个整型数k,接下来3*k个整数用空格隔开,没三个组成一个关系对,每个关系由3个整型数组成i,j,w代表用户i和j的熟悉程度,即r[i][j]=w,没有输入的关系默认为非好友(r[i][j]=r[j][i]=0)。
输出描述
输出T行,每行对应每组测试数据的
用户 i 的 n 度好友,按推荐值降序输出,推荐值相同的好友按好友编号升序。编号间用空格隔开。如果没有n度好友输出-1。
示例
输入
2
10 5 2
13 0 3 5 0 4 9 0 6 8 0 7 5 1 2 6 1 6 3 2 9 7 3 4 3 3 5 3 3 8 3 3 9 3 5 8 9 7 8 9
10 0 2
13 0 3 5 0 4 9 0 6 8 0 7 5 1 2 6 1 6 3 2 9 7 3 4 3 3 5 3 3 8 3 3 9 3 5 8 9 7 8 9
输出
7 0 4 9
1 5 8 9
分析
从大的题型来分析,肯定就是广度优先(bfs)。
先不考虑推荐值,相当于列出在传递n次后能到达的所有好友,并且在题干中明确说明,i度和j度好友是互斥的(i<>j)。从起始点扫描能连通的好友,标记为1度好友,再以多个1度好友为起始点继续传递,到达2度好友,要注意被标记过的点不在传递范围。以此类推就能得到n度好友的列表。
考虑到推荐值,其实是在传递时不断累加好友值,使用临时变量保存即可。
解答
// 这个写法复杂了,有兴趣的可以只使用数组来实现
import java.util.*;
class f {
int i, sum;
public f(int i, int sum) {
this.i = i;
this.sum = sum;
}
}
public class Main_3 {
static List<f> flist = new ArrayList<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System