강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

원재님의 프로필 이미지
원재

작성한 질문수

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

2-Q

2-Q 질문있습니다.

작성

·

22

0

안녕하세요 큰돌님:)

2-Q 문제를 풀었는데 저의 코드가 효율적인지 궁금해서 질문 남깁니다.

http://boj.kr/ef8c0d7a6f54429f964d6471f4d387c5

저의 코드와 큰돌님의 코드의 로직은 비슷한거 같습니다.

다만 큰돌님의 코드는 녹아야 하는 치즈의 영역을 DFS 즉 go함수에서 벡터에 저장하고, 저는 따로 녹이는 함수를 만들어서 진행했습니다.

저의 코드는 함수에서 DFS이후에 한번 더 2 중 for문으로 탐색을 하는 로직이기 때문에 시간 복잡도가 오르는 단점이 있는 거 같습니다.

 

답변 2

0

큰돌님의 프로필 이미지
큰돌
지식공유자

안녕하세요 원재님 ㅎㅎ

사실 이 치즈문제는 굉장히 효율적으로 푸는 방법이 있습니다.

큐 2개를 사용해서 치즈가 녹은 해당 영역부터 다시 탐색을 시작하는 것이죠.

이부분을 보시면 계속해서 초기화 -> 다시 처음 탐색 시점 부터 탐색을 하기 때문에 효율적이지는 않습니다.

*물론 제 코드도 그러한데 이건 난이도 때문에 그렇게 했습니다.

3주차 때 플루드필을 배우면서 보다 효율적으로 탐색하는 것을 배우니 그 때 한번 그걸 치즈에 적용해보시는것도 좋을 것 같습니다.

    while(true){
        memset(visited, 0, sizeof(visited));
        DFS(0,0);
        ret = chck();

 

추석 잘보내세요 ㅎ


 


 

또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.

원재님의 프로필 이미지
원재
질문자

답변 항상 감사합니다 큰돌님:)

큰돌님이 말씀하신 거처럼

제 나름대로 플루드필을 적용해 효율적으로 탐색하려고 코드를 짜봤습니다.

뭔가 깔금하게 코드가 안짜여서 다시 질문해봅니다! 저의 경우 녹인 치즈부터 탐색을 하기 위해 meltList를 선언해서 dfs를 할때 넣습니다. 그리고 meltList의 size가 0이 아니면 해당 meltList부터 탐색을 하고 이전 meltList를 초기화 해주기 위해 temp를 설정했습니다. 뭔가 코테에서 이렇게 짜라고 하면 더 오래 걸릴거 같습니다...

제 코드의 방향이 큰돌님께서 말씀하신 플루드필을 적용한 코드일까요?

http://boj.kr/665df448bcae40569e1829427034b147

큰돌님의 프로필 이미지
큰돌
지식공유자

안녕하세요 원재님 ㅎㅎ

와.... 대박이네요 이걸 dfs로도 이렇게 구현하시다니 ㅎㅎ 놀랍습니다.

정확한 플루드필은 아니지만 그와 유사하게 구현한 것 같습니다.

        for(int i=0; i<temp.size(); i++){
            dfs(temp[i].first, temp[i].second);
        }

개인적으로 이부분이 아쉽습니다. 처음 dfs 호출전에 해당 temp 에 대한 visited 확인하고 호출하는게 더 효율적일 것 같습니다.

 

나머지부분은 다 잘 짜셨습니다.

 


 

또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.

원재님의 프로필 이미지
원재
질문자

답변감사합니다 큰돌님!!

"처음 dfs 호출전에 해당 temp 에 대한 visited 확인하고 호출하는게 더 효율적일 것 같습니다." 이 부분이 제가 이해하기로는 for문안에서

if(visited[temp[i].first][temp[i].second]) continue

를 하라는 말씀인가요?

만약 제가 이해한 바가 맞다면, meltList에 녹는 치즈 좌표가 들어가면서 저는 해당 좌표를 visited[ny][nx] = 1;로 처리합니다. 이러한 로직 때문에 visited를 확인하면 해당 녹인 치즈 좌표부터 탐색이 불가능한거 아닌가요?

큰돌님의 프로필 이미지
큰돌
지식공유자

아 그러네요 ㅎㅎ ㅜ

if(visited[temp[i].first][temp[i].second]) continue은 필요 없고

이 코드에서는 해당 부분은 중복해서 탐색해야할 것 같습니다.

 

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다.

원재님께서 질문해주신 내용을 보니, 2-Q 문제를 해결하면서 본인의 코드와 큰돌님의 코드 간의 효율성을 비교하고 계시는군요. 두 코드의 동작 방식과 효율성에 대해 안내 드리겠습니다.

코드 효율성 비교

  1. 탐색 방식:

    • 큰돌님의 코드는 DFS를 통해 녹아야 할 치즈 영역을 벡터에 저장하여, 한 번의 탐색으로 필요한 모든 정보를 얻고 있습니다. 이는 이후의 처리 과정을 최소화하여 효율성을 높이는 방법입니다.
    • 반면, 원재님의 코드는 DFS 실행 후 별도의 2중 for문을 추가로 돌며 탐색을 수행하셨다고 하셨습니다. 이는 치즈의 상태를 확인하는 과정에서 반복적인 계산이 발생할 수 있어 큰돌님의 방식보다 효율성이 떨어질 수 있습니다.
  2. 시간 복잡도:

    • 말하신대로 2중 for문을 추가로 사용하면, 불필요한 영역까지 여러 번 탐색하게 될 수 있어 시간 복잡도가 증가할 수 있습니다. 문제의 조건 상, 이런 추가적인 탐색이 큰 영향을 미치지 않을 수 있지만, 최적화는 항상 고려될 필요가 있습니다.
  3. 제안사항:

    • 가능하다면, DFS를 활용하여 방문 위치에 따라 바로 처리를 수행하는 방식으로 코드 구조를 변경해보는 것이 좋습니다. 즉, DFS 과정에서 필요한 정보를 축적하고 후속 처리는 최소화하는 방향을 지향해보세요.

관련하여 비슷한 주제의 다른 질문들을 아래에서 살펴보실 수 있습니다:

이렇게 질문을 통해 다양한 방법을 배우고 적용해보는 것은 알고리즘 실력을 향상시키는 좋은 기회가 될 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

원재님의 프로필 이미지
원재

작성한 질문수

질문하기