编程练习打卡1--赛码例题《动脑子认老乡》

最近在准备携程的前端实习笔试,一直搞不清楚这个在线编程输入输出是怎么回事儿,和平时用的代码编辑器压根不一样。刚好看到一个找老乡的例子,正好学习一下这个奇怪的输入输出!

首先是题目描述:

大学的同学来自全国各地,对于远离家乡步入陌生大学校园的大一新生来说,碰到老乡是多么激动的一件事,于是大家都热衷于问身边的同学是否与自己同乡,来自新疆的小赛尤其热衷。但是大家都不告诉小赛他们来自哪里,只是说与谁是不是同乡,从所给的信息中,你能告诉小赛有多少人确定是她的同乡吗?

具体数据输入:

包含多组测试用例。
对于每组测试用例:
第一行包括2个整数,N(1 <= N <= 1000),M(0 <= M <= N*(N-1)/2),代表现有N个人(用1~N编号)和M组关系;
在接下来的M行里,每行包括3个整数,a,b, c,如果c为1,则代表a跟b是同乡;如果c为0,则代表a跟b不是同乡;
已知1表示小赛本人。
输入:
5 4
1 2 1
3 4 0
2 5 1
3 2 1
输出:
3

题目分析:

一开始有点迷路了,想的过于简单了,想着只要判断a或者b是否为1,将满足条件的对应的c值相加。这种情况下只能判断2号是1号小赛的老乡!(错误的代码就不给出来丢人现眼了哈哈哈)咋一看好像没毛病,但是人家给的答案是3啊,也就是小赛是有3个老乡的。画个图就能明白了!其实里面有隐藏的老乡关系,1号和2号是老乡,2号和3号也是老乡,那3号肯定也是1号老乡啊!这么一分析,确实1号是有三个老乡的:2号,3号,5号。

参考大佬们的正确答案,用的是JavaScript编辑器:

// 先是拿到输入的数据
// N代表人数,M代表M组关系,也就是下面多少行
var N,M;
// 创建一个空数组,用来保存明确老乡关系的ab对
var arr=[];
// readInt()用于读取一个长整数,遇到小数点或者空行会自动跳出
while((N=readInt())!=null && (M=readInt())!=null){
    // 循环读取下面的M行,依次取出每一行的a,b,c值
    for(let i=0; i<M; i++){
        let a = readInt(),
            b = readInt(),
            c = readInt();
        // 取出是老乡的一对ab
        if(c==1){
            // 使用三元运算符,从尾部压入arr中
            // 这时候arr为[[1,2],[2,5],[2,3]]
            a<b ? arr.push([a,b]) : arr.push([b,a])
		}
    }
    // 对arr进行排序,保证1号出现在前面
    // 排序后结果为[[1,2],[2,3],[2,5]]
    arr.sort();
    // 如果arr[0][0]不是1则说明1号没有老乡,否则说明1号有老乡
    if(arr[0][0]!=1){
        print(0);   
    }else{
        let re=[];
        // arr[0][1]肯定是1号老乡,先保存
        re.push(arr[0][1]);
        // 现在re里只有一个值2
        // 对arr开始一组一组遍历(相当于在找2号的老乡)
        for(let i=1;i<arr.length;i++){
            if(re.includes(arr[i][0])||re.includes(arr[i][1])){
                // 一旦有,就将这组值压入到re尾部
                re.push(arr[i][0],arr[i][1]);
            }
        }
        // 先Set将arr进行去重,再Array.from将其转化为数组,最后返回长度
        print(Array.from(new Set(re)).length);
    }
}

这是赛码上别人的答案,这里我感觉有点小问题,因为在else代码块中开始时只是将arr[0][1]压入到数组re中,并没有将arr[0][0]也压入,对于题目给的数据肯定没问题的,但是如果实际情况中arr=[[1,2],[1,3],[2,5]],上面的代码就有可能遗漏3号。例如输入数据变为下面情况是得到的结果就是2,但是正确来说应该是3!

输入:
5 4
1 2 1
3 4 0
2 5 1
1 3 1

所以我认为应该把1号也压入到re中,只需在最后求去重后数组re长度是减1就行!!

// 对应else{}代码块
let re=[];
// 将1,2号都保存
re.push(arr[0][0],arr[0][1]);
// 现在re里有两个值[1,2]
// 对arr开始一组一组遍历(分别找1号或2号的老乡)
for(let i=1;i<arr.length;i++){
    if(re.includes(arr[i][0])||re.includes(arr[i][1])){
        // 一旦有,就将这组值压入到re尾部
        re.push(arr[i][0],arr[i][1]);
    }
}
// 先Set将arr进行去重,再Array.from将其转化为数组
// 因为此时数组中是包含1的,所有应该返回长度-1
print(Array.from(new Set(re)).length-1);

首先非常感谢您能够看完,以上代码仅供参考,不保证完全正确,如果有不同看法还请指出。其次本人最近忙于寻找前端实习,如果有什么好的建议还请多多赐教!祝大家生活愉快!

posted @ 2021-05-12 09:45  仙贝wang  阅读(204)  评论(0)    收藏  举报