Algorithm/Baekjoon(Node.js)

[JavaSrcipt] Baekjoon - 2231 : 분해합

비망노트 2021. 10. 14. 23:21

문제

어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이 된다. 따라서 245는 256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다.

자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 N(1 ≤ N ≤ 1,000,000)이 주어진다.

출력

첫째 줄에 답을 출력한다. 생성자가 없는 경우에는 0을 출력한다.

 

예제입력 예제출력
216 198

 

⭕ 풀이

const input=require('fs').readFileSync('/dev/stdin').toString().trim();
const n=Number(input);

function divide(num){
    
    let arr=num.toString().split('').map(x=>Number(x));
    return arr.reduce((a,v)=>a+v);
    
}

let i;
if(n>100000){i=n-(9*6)}
else if(n>10000){i=n-(9*5)}
else if(n>1000){i=n-(9*4)}
else if(n>100){i=n-(9*3)}
else{i=1};

let answer=0;
while(i<=n){
    
    if(i+divide(i)==n){
        answer=i;
        break;
    }
        
    i++;
}
console.log(answer);

 

처음에는 브루트포스 전체검증에 맞게

i를 0으로 하고 if문에서 i의 값을 정해주는실행문 없이 제출해보았다.

정답이긴했지만 제한시간2초여서 다행이지 1000ms를 넘었다.

그래서 각 자릿수마다 최대값이 9이므로 입력최대값이 1000000이 주어진다고했으므로

범위를 줄여 테스트할 수 있도록 if문에 i의값을 정의해주었다.

 

예를들어 입력값이 987654 라면 각 자릿수에 들어갈수있는 최대값9 6개가 가능하므로

입력값에서 9*6을 뺀값을 i로 지정해주고 해당 값부터 while문을 실행하면되는것이다.

 

이렇게 제출하니 120ms로 거의 10배넘게 줄었다.

입력값이 제한되어있으므로 저렇게 쓰긴했으나

const input=require('fs').readFileSync('/dev/stdin').toString().trim();
const n=Number(input);

function divide(num){
    
    let arr=num.toString().split('').map(x=>Number(x));
    return arr.reduce((a,v)=>a+v);
    
}

❗ let idx=input.length;
❗ let i=n-(9*idx);

let answer=0;

while(i<=n){
    
    if(i+divide(i)==n){
        answer=i;
        break;
    }
        
    i++;
}
console.log(answer);

이렇게 간단하게 적을 수 있다.

이때 idx=n.length로 하면 n은 형식이 숫자라서 idx가 제대로 길이를 받지못하므로

string형식인 input의 길이를 가져와야한다.

 

또 while문 내 if문에 console.log(i) 후 break를 해도되겠지만

그럴경우 생성자가 없을경우 0을 출력해주는 실행문을 또 넣어주어야하므로

자칫하면 0이 계속출력되어 에러가 나올 수 있다. 내가그랬다.

그러므로 처음부터 answer의 값을 0으로 정의하고 짜도록했다.

 

 

 

 

-출처

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