정수 s가 주어진다. 정수 s의 값을 t로 바꾸는 최소 연산 횟수를 구하는 프로그램을 작성하시오.
사용할 수 있는 연산은 아래와 같다.
첫째 줄에 s와 t가 주어진다. (1 ≤ s, t ≤ 109)
첫째 줄에 정수 s를 t로 바꾸는 방법을 출력한다. s와 t가 같은 경우에는 0을, 바꿀 수 없는 경우에는 -1을 출력한다. 가능한 방법이 여러 가지라면, 사전 순으로 앞서는 것을 출력한다.
연산의 아스키 코드 순서는 '*', '+', '-', '/' 이다.
입력 출력
7 392 +*+
dfs
로 풀고자 했다.
[연산값, '연산횟수']
형식으로 넣어준다.[[15, '*+'], [40, '+-+'], [58, '++*-']]
첫 시도 :
pop
으로 했을 때는 answer에 값이 전부 안담겼다.
두 번째 시도 :shift
로 했을 때는 테스트케이스는 맞았지만 정답은 틀렸다.
세 번째 시도 :연산 길이가 작은 것을 항상 먼저 체크하도록
+pop
으로 해서 맞았다.(시간은 좀 오래 걸렸지만)
const input = require('fs').readFileSync('ex.txt').toString().trim().split(' ');
const [s, t] = input.map(Number);
if (s === t) {
console.log(0);
} else {
let stack = [];
stack.push([s, '']);
let visited = {};
let answer = [];
while (stack.length) {
let [n, calc] = stack.pop();
if (!visited[n]) {
visited[n] = true;
if (n === t) {
answer.push(calc);
} else {
stack.push([n + n, calc + '+']);
stack.push([n * n, calc + '*']);
stack.push([n - n, calc + '-']);
stack.push([n / n, calc + '/']);
}
}
stack.sort((a, b) => b[1].length - a[1].length); // 연산횟수 적은 것부터 탐색하기 위함
}
if (answer.length === 0) {
console.log(-1);
} else if (answer.length === 1) {
console.log(answer.join(''));
} else {
let list = answer.sort((a, b) => a.length - b.length); // 길이 오름차순 정렬
let min_list = list.filter((el) => el.length === list[0].length); // 길이 같은거 여러개인지 체크
if (min_list.length === 1) {
console.log(min_list.join(''));
} else {
console.log(min_list.sort()[0]); // 사전순 정렬
}
}
}