lintcode 873 模拟松鼠(JavaScript)

有一颗树,一只松鼠,和几个见过,位置由二维网络中的单元格表示。你的目标是找到最短距离,让松鼠收集所有的见过,并把它们一个一个地放在树下。松鼠每次只能携带一个坚果。可以在四个方向上移动——上、下、左、右,到相邻的单元格。距离用移动的次数表示。

所有给定的位置都不会重叠;

松鼠一次只能携带一个坚果;

给定的坚果位置没有顺序;

宽度和高度是正整数。3 <= 高度 * 宽度 <= 10,000。

给定的网格中至少包含一个坚果,但只有一棵树和一只松鼠。

例子:

输入:height=5, width=7, tree=[2,2], squirrel=[4,4], nuts=[[3,0],[2,5]]

输出:12

解释:

网格规模5 * 7,树在(2,2),松鼠在(4,4),有两个坚果,分别在(3,0),(2,5)。
松鼠先去(2,5)拿坚果,放到树下,然后去拿(3,0)的坚果,放到树下。
总共走了:3 + 3 + 3 + 3 = 12 步。

思路:

首先,计算两点的距离,就是横纵坐标的差的绝对值的和。

const distance = (a, b) => {
    return Math.abs(a[0], b[0]) + Math.abs(a[1], b[1]);
}

松鼠的移动轨迹是:先到一个坚果处,然后走到树,最后在树和剩下的坚果之间往返。所以只要找出第一个坚果,就好说。

我最开始想到的是,第一个坚果就应该是离松鼠最近的那个,结果发现错误。画了图之后发现的确不行,

0    0   0    0   0
0    0   0    0   0
0    树  0    0   果1
果2  0   果3  0   0
0    0   0    鼠  0


坚果3离松鼠最近,但计算一下,就会发现,首先去坚果1,距离是最短的。

试验多次,发现:(我们要遍历坚果,找出最先走的那一个,最先走的坚果first初始值为nuts第一个元素)若当前坚果与树的距离之和first坚果与松鼠的距离之和 大于 当前坚果与松鼠的距离和first坚果与树的距离之和,就更新first坚果为当前坚果。

这句话很绕,多读几遍。

    for (let i in nuts) {
        let now = distance(nuts[first], squirrel) + distance(nuts[i], tree),
            before = distance(nuts[i], squirrel) + distance(nuts[first], tree);
        if (now > before) 
            first = i;
    }

求出第一个要去坚果之后,从nuts坚果数组中删掉这个坚果,计算其他坚果与树的距离的2倍的总和,加上第一次去坚果与第一次去树的距离,即为最终结果。

/**
 * @param height: the height
 * @param width: the width
 * @param tree: the position of tree
 * @param squirrel: the position of squirrel
 * @param nuts: the position of nuts
 * @return: the minimal distance 
 */
const minDistance = function (height, width, tree, squirrel, nuts) {
    // Write your code here
    const distance = (a, b) => {
        return Math.abs(a[0]-b[0]) + Math.abs(a[1]-b[1]);
    }
    let first = 0;    // 第一次去最近的坚果
    for (let i in nuts) {
        let now = distance(nuts[first], squirrel) + distance(nuts[i], tree),
            before = distance(nuts[i], squirrel) + distance(nuts[first], tree);
        if (now > before) 
            first = i;
    }
    let firstDistance = distance(nuts[first], squirrel) + distance(nuts[first], tree);
    let res = firstDistance;
    nuts.splice(first, 1);
    for (let nut of nuts) {
        res += distance(nut, tree)*2;
    }
    return res;
}

PS:输入参数中的 height 与 width 没用!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的桐人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值