https://www.acmicpc.net/problem/1744

//test.txt
4
-1
2
1
3
sol1
let [_,...input] = require('fs').readFileSync('test.txt').toString().trim().split('\n');
let arr = input.map(Number);
function solution(arr) {
let plusArr = arr.filter(el => el>0).sort((a,b) => b-a);
let minusArr = arr.filter(el => el<=0).sort((a,b) => a-b);
let plusLen = plusArr.length;
let minusLen = minusArr.length;
let plusAns = ifCase(plusArr,plusLen);
let minusAns = ifCase(minusArr,minusLen);
let answer = 0;
if(plusLen && minusLen) {
answer += plusAns + minusAns;
}else if(plusLen) {
answer += plusAns;
} else answer += minusAns;
return answer;
};
function ifCase(Arr,Len) {
let answer = 0;
if(Len === 1) return answer += Arr[0];
if(Len%2 === 0) {
answer += cal(Arr);
} else {
answer += Arr.pop();
answer += cal(Arr);
};
return answer;
};
function cal(array) {
let answer = 0;
while(1) {
let a = array.shift();
let b = array.shift();
answer += compare(a,b)
if(array.length === 0) break;
}
return answer;
};
function compare(a,b) {
if(a<0 && b<0) return a*b;
else {
let multiply = a*b;
let cal = a+b;
return Math.max(multiply,cal);
}
};
console.log(solution(arr));
// 6
논리는 어렵지 않았지만 똑같이 생긴 for문이나 변수를 여러 번 써야 할 거 같아서 미리 함수를 만들어 해결했다. 이런 방식으로 문제를 해결해보기는 처음인데 불필요한 부분도 있는 거 같고.. 깨끗한 코드 같지는 않다. 비슷한 문제를 해결해보며 익숙해지는 시간을 가져야겠다.
1.
function solution(arr) {
let plusArr = arr.filter(el => el>0).sort((a,b) => b-a);
let minusArr = arr.filter(el => el<=0).sort((a,b) => a-b);
let plusLen = plusArr.length;
let minusLen = minusArr.length;
let plusAns = ifCase(plusArr,plusLen);
let minusAns = ifCase(minusArr,minusLen);
let answer = 0;
if(plusLen && minusLen) {
answer += plusAns + minusAns;
}else if(plusLen) {
answer += plusAns;
} else answer += minusAns;
return answer;
};
입력받은 배열을 양수와 음수로 나눠 각각 배열을 만든다. 이때 양수 배열은 내림차순, 음수 배열은 오름차순으로 정렬한다. 결국 목적은 가장 큰 값을 맞춰야 하는데 양수의 경우 큰 수 끼리 곱하도록 하고, 음수의 경우 절댓값이 큰 수 끼리 곱하는 경우가 가장 크기 때문이다.
함수에 넣을 때마다 배열의 길이를 넣어줘야 하기 때문에 길이도 따로 저장해 두었다.
양수 배열의 최댓값, 음수 배열의 최댓값을 저장해 두고 최초 입력받은 배열이 양수만 있는 경우, 음수만 있는 경우, 둘 다 있는 경우에 따라 answer에 넣어주면 된다. 이 경우 if문을 사용했는데 단순히 if(양수) if(음수)로 했다가 함수가 꼬여서 한참을 고생했다. 조건의 범위를 잘 못줘서 양수와 0이 있는 경우를 잘못 돌고 있는 거 같은데, 처음 겪어보는 상황이라 한참 헤맸다. if문을 사용할 때는 조건을 구체적으로 명시하고, else if나 else로 들어와야 할 부분인지 새로운 if 문을 만들어야 하는 부분인지 잘 구별해야겠다.
2.
function ifCase(Arr,Len) {
let answer = 0;
if(Len === 1) return answer += Arr[0];
if(Len%2 === 0) {
answer += cal(Arr);
} else {
answer += Arr.pop();
answer += cal(Arr);
};
return answer;
};
양수든 음수든, 배열의 길이가 1인 경우는 곱하거나 더할 필요가 없기 때문에 그냥 출력으로 보내주고 함수를 끝낸다. 배열의 길이가 짝수인 경우와 홀수인 경우는 별도로 두어야 하는데, 배열의 두 요소끼리 비교해야 하기 때문이다. 만약 배열이 홀수라면 제일 작은 값을 출력으로 보내줘 짝수 배열로 만들어줘야 한다. 이미 정렬된 배열이기 때문에 음, 양 모두 마지막 요소가 제일 작으며 pop()으로 마지막 요소만 꺼내 미리 출력 변수에 보내 둔다.
3.
function cal(array) {
let answer = 0;
while(1) {
let a = array.shift();
let b = array.shift();
answer += compare(a,b)
if(array.length === 0) break;
}
return answer;
};
2. 을 거치며 짝수인 배열만 함수에 들어올 것이다. 정렬된 배열에서 순서대로 두 개를 뺀 후 더한 값이 큰지 곱한 값이 큰 지 비교한다. 두 요소중 하나가 1인 경우가 아니면 곱셈이 항상 클 테지만, 요소중 하나가 1인 경우를 다시 예외 처리하는 것보다 깔끔하게 비교 함수를 만들기로 했다. while을 도는 내내 순서대로 두 요소씩 뽑아 사용하며, 배열의 길이가 0이라면 멈추고 answer값을 보내주며 끝난다.
4.
function compare(a,b) {
if(a<0 && b<0) return a*b;
else {
let multiply = a*b;
let cal = a+b;
return Math.max(multiply,cal);
}
곱한 값과 더한 값을 비교하기 위한 함수이다. 3. 에서 설명한 것처럼 곱셈을 하되 1, -1 인경우를 예외처리 하는 방법도 있을 것이다.

하던 대로 for문 잔뜩 써서 해결했다면 가독성은 조금 떨어져도 빨리 해결했을 텐데.. 시간은 좀 더 걸렸지만 이런 모양으로 만들어 보는 것도 재밌는 것 같다.
'Study > Algorithm' 카테고리의 다른 글
[programmers / JavaScript] 기능 개발 (0) | 2022.06.22 |
---|---|
[BEAKJOON / node.js] 1302 베스트셀러 (0) | 2022.06.21 |
[BEAKJOON / node.js] 12904 A와 B (0) | 2022.06.16 |
[BEAKJOON / node.js] 9935 문자열 폭발 (0) | 2022.06.15 |
[programmers / JavaScript] JadenCase 문자열 만들기 (0) | 2022.06.14 |