题目描述
你正在玩一个单人游戏,面前放置着大小分别为 a、b 和 c 的 三堆 石子。
每回合你都要从两个 不同的非空堆 中取出一颗石子,并在得分上加 1 分。当存在 两个或更多 的空堆时,游戏停止。
给你三个整数 a 、b 和 c ,返回可以得到的 最大分数 。
示例 1:
输入:a = 2, b = 4, c = 6
输出:6
解释:石子起始状态是 (2, 4, 6) ,最优的一组操作是:
- 从第一和第三堆取,石子状态现在是 (1, 4, 5)
- 从第一和第三堆取,石子状态现在是 (0, 4, 4)
- 从第二和第三堆取,石子状态现在是 (0, 3, 3)
- 从第二和第三堆取,石子状态现在是 (0, 2, 2)
- 从第二和第三堆取,石子状态现在是 (0, 1, 1)
- 从第二和第三堆取,石子状态现在是 (0, 0, 0) 总分:6 分 。
示例 2: 输入:a = 4, b = 4, c = 6 输出:7 解释:石子起始状态是 (4, 4, 6) ,最优的一组操作是:
- 从第一和第二堆取,石子状态现在是 (3, 3, 6)
- 从第一和第三堆取,石子状态现在是 (2, 3, 5)
- 从第一和第三堆取,石子状态现在是 (1, 3, 4)
- 从第一和第三堆取,石子状态现在是 (0, 3, 3)
- 从第二和第三堆取,石子状态现在是 (0, 2, 2)
- 从第二和第三堆取,石子状态现在是 (0, 1, 1)
- 从第二和第三堆取,石子状态现在是 (0, 0, 0) 总分:7 分 。
示例 3:
输入:a = 1, b = 8, c = 8
输出:8
解释:最优的一组操作是连续从第二和第三堆取 8 回合,直到将它们取空。
注意,由于第二和第三堆已经空了,游戏结束,不能继续从第一堆中取石子。
变量的解构赋值
以前,为变量赋值,只能直接指定值。
let a = 1;
let b = 2;
let c = 3;
ES6允许写成下面这样
let [a, b, c] = [1, 2, 3];
上面的代码表示,可以从数组中提取值,按照对应位置,对变量赋值。
用途
(1)交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
上面代码交换变量x和y的值,这样的写法不仅简洁,而且易读,语义非常清晰。
(2)从函数返回多个值
函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回,有了解构赋值,取出这些值就非常方便。
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
};
let {foo, bar} = example();
(3)函数参数的定义
(4)提取JSON数据
(5)函数参数的默认值
(6)遍历Map结构
(7)输入模块的指定方法
解题思路
- 先判断a,b,c的大小,并交换a,b,c的值,使得a,b,c变成从小到大的排序。
- 第一步:让a和c-b之间做最小值比较。得到另一个值cnt1。然后a和c分别减cnt1。ans加cnt1。
- 第二步:判断a是否还有值剩下,如果没有值剩下,那么ans直接加b,并返回
- 第三步:如果a还有值剩下,那么对剩余的a做奇偶数判断。如何是奇数,那么一定会有一个值剩下。所以直接将a赋值为a - 1.如果为偶数,那么平均分配到b和c上面。让b和c分别减a/2。ans加a。然后执行第二步操作。
代码
var maximumScore = function(a, b, c){
// 交换abc的值
if(a > b) [a, b] = [b, a];
if(a > c) [a, c] = [c, a];
if(b > c) [b, c] = [c, b];
let ans = 0;
// setp1,取出a和c - b中的小值
let cnt1 = Math.min(c - b, a);
a -= cnt1;
c -= cnt1;
ans += cnt1;
// step2,如果a还有值剩余
if(a != 0){
if(a % 2 == 1) a -= 1;
b -= a / 2;
c -= a / 2
ans += a;
}
// step3,直接加上b
ans += b;
return ans;
}