3의 제곱수를 생각하자. 3의 0제곱, 3의 1제곱, 3의 2제곱, ... 은 순서대로 1, 3, 9, 27, ... 이 된다.
이를 바탕으로, 한 개 이상의 서로 다른 3의 제곱수의 합으로 표현되는 수를 생각할 수 있다. 예를 들어 30은 27과 3의 합이므로, 이러한 수에 포함된다.
한 개 이상의 서로 다른 3의 제곱수의 합으로 표현되는 N번째로 작은 수를 구하는 프로그램을 작성하시오.
첫째 줄에 N이 주어진다. N은 500,000,000,000 이하의 자연수이다.
첫째 줄에 한 개 이상의 서로 다른 3의 제곱수의 합으로 표현되는 N번째로 작은 수를 출력한다.
4
9
var fs = require('fs');
var input = fs.readFileSync('/dev/stdin').toString().trim();
let n = BigInt(input);
let binary = '';
while (true) {
if (n === 0n) break;
binary = (n % 2n) + binary;
n = n / 2n;
}
let answer = 0n;
let pow = 0n;
for (let i = binary.length - 1; i >= 0; i--) {
answer += BigInt(binary.charAt(i)) * getPow(pow++);
}
console.log(answer.toString());
function getPow(n) {
let pow = 1n;
for (let i = 0n; i < n; i++) {
pow *= 3n;
}
return pow;
}
3진수로 변환하는 코드를 작성했는데 "서로 다른"에 대한 조건을 해결할 수 없어서 다른 사람들의 풀이를 참고하게 된 문제.. 결과적으로 2진수 변환을 먼저 해주어야 했다는 점... 참신한 풀이이긴 하나 다음에 유사한 문제를 발견하면 그 때 기억할 수 있을 것인가... 조금이라도 기억을 오래하기 위해 기록하긴 하지만, 비트마스킹 문제는 정말 어렵고 어렵고 어려운 것 같다. 또, 숫자가 커지면서 거듭제곱 함수를 사용하면 값에 차이가 발생할 수 있다고 해서 거듭제곱을 함수로 구현했다. 문제를 풀기위해서는 가끔씩 편리한 메소드를 직접 구현해야 할 때가 있겠구나를 생각하게 됐다.