Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 프로그래머스
- Dynamic Programming
- dfs
- Lv. 0
- 파이썬
- LEVEL 2
- 오블완
- 티스토리챌린지
- Lv. 3
- softeer
- SQL 고득점 KIT
- 너비 우선 탐색
- 동적계획법
- SQL
- javascript
- select
- programmers
- 깊이 우선 탐색
- level 3
- Lv. 1
- group by
- DP
- Python
- 소프티어
- C언어
- bfs
- 자바스크립트
- Java
- join
- Lv. 2
Archives
- Today
- Total
몸과 마음이 건전한 SW 개발자
Softeer [Level 3] 수퍼바이러스 {언어 : JavaScript} [BigInt] 본문
문제 링크
https://softeer.ai/practice/6292
정답 코드
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const inputData = [];
rl.on('line', (line) => {
inputData.push(line.split(" ").map((e) => Number(e)));
}).on('close', () => {
const [k, p, n] = inputData[0];
const divide = BigInt(1000000007);
// 1초 10초 100초 ... 10**16초
// 10초는 1초를 10제곱
const bigIntP = BigInt(p);
const dp = Array(17).fill(BigInt(1));
for (let i = 0; i < 10; i++) {
dp[0] = (dp[0] * bigIntP) % divide;
}
for (let j = 1; j < 17; j++) {
for (let l = 0; l < 10; l++) {
dp[j] = (dp[j] * dp[j-1]) % divide;
}
}
const stack = [];
let count = n;
while (count >= 1) {
stack.push(count % 10);
count = Math.floor(count / 10);
}
const answer = stack.reduce((sum, e, idx) => {
let tmp = BigInt(1);
for (let m = 0; m < e; m++) {
tmp = (tmp * dp[idx]) % divide;
}
return (sum * tmp) % divide;
}, BigInt(k)).toString();
console.log(answer);
process.exit(0);
});
풀이 방법
- 0.1초당 p배씩 증가하므로 n이 10^16인 경우 10^17번 연산을 해야한다.
- 이렇게 계산 할 수도 있지만 대략 10^8(1억)번이 1초라고 생각하면 10^8초???
- 결국 수작업으로 하나하나 계산하는 방식은 선택할 수 없다.
- 다음 고려할 부분은 10^8 * 10^8 이상인 경우
- 자바스크립트의 안전한 정수 범위는 −9,007,199,254,740,991부터 까지 (약 9×10^15)
- 따라서 BigInt를 사용해야 한다.
- 계산하는 방법은 다음과 같다.
- 1초 일때는 p^10 => 이를 계산한 값을 pt이라고 하면
- 10초 일 때는 p^10^10 = pt^10
- 이런식으로 10^16초까지 구해서 dp에 넣는다.
- dp[0]이 1초 = p^10
- 이후 10의 자리수를 뒤에서부터 stack에 넣고 배열을 만든다.
- 1876 = stack{6, 7, 8, 1}
- reduce를 이용해서 누적 값을 구한다.
- dp[0]^6 * dp[1]^7 * dp[2]^8 * dp[3]^1 * K % 1000000007
- 값을 toString()으로 변환하고 출력하면 끝!
- BigInt를 그대로 출력하면 1827n이렇게 나온다.
느낀점
- 숫자가 10^16 언저리에서 계산하면 BigInt없이도 될거라고 생각했는데 아니었다.
- 9*10^15정도 되면 BigInt를 쓰도록 하자.