인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

ncc0816님의 프로필 이미지

작성한 질문수

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

3-B

3-B번 질문 있습니다!

해결된 질문

작성

·

35

0

3-B번 보물섬 문제를 풀다가. 각 육지마다 BFS를 하는 것보다, 한 컴포넌트에서 BFS_1로 임의의 한 점에서 가장 먼 점을 찾고, 찾은 가장 먼 점에서 BFS_2로 또 가장 먼 점을 찾으면, 해당 컴포넌트에서는 가장 먼 점의 길이를 구할 수 있다고 생각하고 풀이하였는데 틀린 이유를 잘 모르겠습니다...

이렇게 풀면 틀린 이유가 있을까요??

항상 수업 너무 잘 듣고 있습니다. 감사합니다!

#include <bits/stdc++.h>
using namespace std;

int n, m;
string a;
char mapp[54][54];
bool visited[54][54];
int dis[54][54];
int dy[] = {0,-1,0,1};
int dx[] = {1,0,-1,0};
queue<pair<int,int>> q;
queue<pair<int,int>> q2;
int max_val = 0;

pair<int,int> bfs_1(int y, int x){
  visited[y][x]=1;
  q.push({y,x});
  pair<int,int> here;
  while(q.size()){
    here = q.front();
    q.pop();
    for(int i=0;i<4;i++){
      int ny = here.first + dy[i];
      int nx = here.second + dx[i];
      if(ny<0||nx<0||ny>=n||nx>=m) continue;
      if(visited[ny][nx]) continue;
      if(mapp[ny][nx]=='W') continue;
      visited[ny][nx] = 1;
      q.push({ny,nx});
    }
  }
  return here;
}

int bfs_2(int y, int x){
  dis[y][x] = 1;
  q2.push({y,x});
  pair<int,int> here;
  while(q2.size()){
    here = q2.front();
    q2.pop();
    for(int i=0;i<4;i++){
      int ny = here.first + dy[i];
      int nx = here.second + dx[i];
      if(ny<0||nx<0||ny>=n||nx>=m) continue;
      if(dis[ny][nx]>0) continue;
      if(mapp[ny][nx]=='W') continue;
      dis[ny][nx] = dis[here.first][here.second] + 1;
      q2.push({ny,nx});
    }
  }
  return dis[here.first][here.second];
}


int main(){
  cin >> n >> m;
  for(int i=0;i<n;i++){
    cin >> a;
    for(int j=0;j<a.length();j++){
      mapp[i][j] = a[j];
    }
  }

  for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
      if(mapp[i][j]=='W') continue;
      if(visited[i][j]) continue;
      pair<int,int> ret_1 = bfs_1(i,j);
      int max_dis = bfs_2(ret_1.first, ret_1.second) -1;
      max_val=max(max_val,max_dis);
    }
  }
  cout << max_val;
  return 0;
}

답변 2

0

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

안녕하세요 ㅎㅎ

이부분은 사이클 떄문에 일어나는 반례입니다.

ncc님의 로직은 트리일 때 가장 긴 정점(지름)을 구하는데는 유효합니다.

하지만 이 문제의 경우 전부다 양방향간선이라고 볼 수 있고 그렇기 때문에 사이클이 존재해서 반례가 생깁니다.

제가 한번 그림을 그려봤습니다. ㅎㅎ

스크린샷 2025-04-07 오후 2.08.56.png.webp

앞의 그림처럼 e에서 bfs가 시작이 되면 a, c라는 정점이 당첨, c에서 시작한다고 했을 때 최장거리는 2가 되어버립니다. 정답은 a ~ d여서 3인데 말이죠. ㅎㅎ

이러한 반례 때문에 안되는 것 같습니다.

 

그리고 전반적으로 코드 자체는 잘 짜셨습니다. ㅎㅎ


 


 

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

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

감사합니다.

강사 큰돌 올림.

0

인프런 AI 인턴님의 프로필 이미지

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

ncc0816님, 보물섬 문제는 각 육지(“L”)에서 시작하여 가장 먼 두 점 간의 거리를 구하는 문제입니다. 주어진 코드는 각 육지 컴포넌트에서 BFS를 수행하여 가장 먼 점을 찾고, 그 점에서 다시 BFS를 수행하는 방식으로 해결하고자 하셨습니다. 하지만 아래 몇 가지 점검 사항을 고민해 보시면 좋겠습니다.

문제점 분석 및 검토 사항

  1. 방문 배열 초기화: 각 bfs_1bfs_2 함수 호출 전에 visiteddis 배열을 초기화하지 않는다면, 이전 BFS 탐색의 잔여 값들이 영향을 미칠 수 있습니다. 각 새로운 시작점마다 배열을 초기화하는 것이 필요합니다.

  2. 올바른 거리 계산: bfs_2에서 dis값의 초기화는 dis[y][x] = 1;로 설정되어 처음 방문한 점에서 초기 거리를 설정하지만, 이로 인해 -1 값을 반환해야 합니다. 이 부분이 맞지 않는 경우가 발생할 수 있습니다.

  3. BFS 과정의 적절성: BFS가 정상적으로 모든 가능한 길을 탐색해야 합니다. 가령, q.push 이후 visiteddis 업데이트 시 한 번 더 검토 후 다음 BFS로 전달이 올바르게 되는지 확인합니다.

  4. 컴포넌트 경계 조건 확인: 각 BFS가 정확히 경계까지 탐색하여 적절하게 컴포넌트를 구분하는지 검토해 보세요.

일반적인 해결 방법

기본적으로 보물섬 문제는 모든 육지에서 BFS를 수행하여 각각의 최대 거리를 체크하는 것이 일반적인 접근 방식입니다. 님의 접근 방법도 좋은 방향이지만, 구현상 미세한 차이로 문제를 틀릴 수 있습니다. 또한 작은 변수나 경계 조건에서 문제가 있을 수 있으므로, 추가적으로 디버깅을 통해 조건과 출력값을 검증해 볼 필요가 있습니다.

추가 리소스

  • BFS를 이용한 거리 계산 관련 내용을 보시고 문제가 잘 파악되지 않을 경우 어떻게 해결했는지 참고하시면 좋겠습니다.

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

ncc0816님의 프로필 이미지

작성한 질문수

질문하기