해결된 질문
작성
·
309
1
안녕하세요. 선생님 ㅎㅎ 수업 잘 듣고 있습니다.
수업에서 알려주신 visited 배열의 값들을 증가시키면서 depth를 세는 방법 말고, 구조체를 정의해서 문제를 풀어봤는데요?
이게 어떤 방법은 틀리고 어떤 방법은 맞아서.. 어디서 차이가 나는지 궁금해서 질문드립니다.
<맞은 코드>
http://boj.kr/646d439f862e419ab3a865fdd7b1551b
일단 큐에 현재 노드에서 갈 수 있는 노드(4방향)를 모두 넣고, 이후에 조건으로 노드를 선별하고, 혹시나 해서 아래와 같은 탈출 조건을 추가했습니다.
if (row == m - 1 && col == n - 1) {
res = depth;
break;
}
<틀린 코드>
http://boj.kr/516fe108a71c492e8c1967455f7222a1
이번에는 큐에 넣기 전 예상되는 노드를 조건문을 통해서 선별하고 큐에 넣습니다.
제 생각에는 이 코드가 큐에 들어가는 노드의 개수가 적어서 속도가 빠를 것 같은데, 메모리 초과가 나오더라구요;;
<수정 코드>
http://boj.kr/f72b373b45464778b8313fec9713ba18
수정을 해봤는데 이번에는 틀린 코드랑 나머지는 똑같은데 반복문 안에서 큐에 넣자마자 바로 방문처리를 해주는 것입니다.
for (int i = 0; i < 4; i++) {
int nr = row + dr[i];
int nc = col + dc[i];
if (nr < 0 || nr >= m || nc < 0 || nc >= n) {
continue;
}
if (puzzle[nc][nr] == 0) {
continue;
}
if (visited[nc][nr]) {
continue;
}
q.push({nr, nc, depth + 1});
visited[nc][nr] = true;
}
이렇게 수정하니까 또 맞더라구요..
<수정 코드>가 <틀린 코드>보다 메모리를 덜 차지하는 것은 알겠는데, <맞은 코드>가 <틀린 코드>보다 메모리를 덜 차지하는 잘 모르겠어서 질문드립니다.
질문이 길어서 sorry...
답변 1
1
안녕하세요 인교님 ㅎㅎ
일단 메모리 초과같은 경우는 무엇때문에 메모리초과가 난다고는 정확하게 설명하지는 못합니다. 정말 메모리를 효율적으로 했음에도 불구하고 문제의 메모리 제한 때문에 그런 경우도 발생하거든요.
그렇기 때문에 이렇게 접근하는게 좋습니다.
"비효율적인 부분이 있을까?"
자 그러면 인교님이 말씀하신
이번에는 큐에 넣기 전 예상되는 노드를 조건문을 통해서 선별하고 큐에 넣습니다.
제 생각에는 이 코드가 큐에 들어가는 노드의 개수가 적어서 속도가 빠를 것 같은데, 메모리 초과가 나오더라구요;;
>> 조건문을 통해서 선별해서 넣은 부분을 볼게요.
if (nr < 0 || nr >= m || nc < 0 || nc >= n) {
continue;
}
if (puzzle[nc][nr] == 0) {
continue;
}
if (visited[nc][nr]) {
continue;
}
조건문을 통해서 넣죠. 그러나.
q.push({nr, nc, depth + 1});
이런식으로 방문처리는 하지 않고 q에 넣고 있습니다.
이 경우 이런 문제가 발생합니다.
지금 보시는 것처럼 빨간색 노드가 q에 들어가는 것을 볼 수 있죠? 방문처리를 안했고 그때문에 해당 노드가 중복되서 들어가는 것을 볼 수 있습니다.
이 때문에 노드가 더 queue에 들어가기 때문에 메모리적으로 시간적으로 비효율적인 부분이 발생하는 것 같습니다.
또 질문 있으시면 언제든지 질문 부탁드립니다.
좋은 수강평과 별점 5점은 제가 큰 힘이 됩니다. :)
감사합니다.
강사 큰돌 올림.