题解 | #数组分组#
数组分组
http://www.nowcoder.com/practice/9af744a3517440508dbeb297020aca86
1.将3的放一边,5的放另外一边,用3的倍数集合减5的倍数集合的值作为临界点和剩下的进行比较。
2.将数组全部转变为正整数进行运算,取最大的两个数的相减值和剩余的值进行排序,递归,如果大
的值-小的值一直减下去是0,则代表可以分完。本题难点就是先将数组全部变为正整数。
解释:将剩下的数当做别人欠你的钱或者是你借给别人的钱,而你身上的钱就是arr3 - arr5,可能是你借别人的,也可能是别人借你的。
如果你将arr3 - arr5的钱又借出去,那么你就没钱了,身上是0,现在就是将别人的欠你的钱去还你借别人的钱,如果刚好你能还清
则代表你不欠钱,还不清就是你还欠别人钱或者别人欠你钱。
let line;
let arr = []
function getRes (arr){
let arr1 = [];
let arr2 = [];
let arr3 = [];
for(let i = 0;i<arr.length;i++){
if(arr[i] % 3 == 0 && arr[i] % 5 != 0){
arr1.push(arr[i])
}else if(arr[i] % 3 != 0 && arr[i] % 5 == 0){
arr2.push(arr[i])
}else{
arr3.push(arr[i])
}
}
let num1 = getSum(arr1);
let num2 = getSum(arr2);
let summeries = num1 - num2;
let flag = getCalc(arr3,summeries)
return flag
}
function getCalc(arr,summeries){
let flag = false
if(summeries == 0 && arr.length == 0){
// 分完了 两边值的差值一样则代表可以分为两组
flag = true
return flag
}else if(arr.length == 0 && summeries!=0){
// 分完了但是值不想等 或者是值相等还有剩的
return flag
}else {
arr.push(summeries)
arr = arr.map(i=>Math.abs(i));
arr = arr.sort((a,b)=>a-b);
summeries = arr[arr.length - 1]
arr.splice(arr.length - 1,1);
// 将数据进行遍历取绝对值,因为是两边放左边和放右边是一样,但是值要取反,
// 举个例子1 -5 -1 -3 2 -4 将-5放左边和放右边进行运算 和+5放左边进行运算结果是一样的 运算指(+-)
// 题目中虽然给了负数但是我们把它当做正整数处理就很好处理了
// 将数据进行排序然后取 最大的两个进行相减然后结果进行递归处理
// 第一次的结果放入第二次运算中进行排序相减 当全部处理完这个值如果不是0,则代表分不完
let numDescrease = arr[arr.length - 1];
arr.splice(arr.length - 1,1);
let current = summeries - numDescrease
flag = getCalc(arr,current)
}
return flag
}
function getSum (arr){
let num = 0
if(arr.length == 0){
return num
}
for(let i of arr){
num+=parseInt(i)
}
return num
}
while(line = readline()){
arr.push(line);
if(arr.length == 2){
let arr1 = arr[1].trim().split(' ').map((i)=>parseInt(i));
let res = getRes(arr1);
arr = []
console.log(res)
}
}