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

kimseunghwan7777님의 프로필 이미지
kimseunghwan7777

작성한 질문수

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

3-C

질문

작성

·

491

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

 

http://boj.kr/651b3f6555054253aff3c5af3b037dbb

이전에도 visited 위치에 대해서 질문한 적이 있는데, 이번에도 질문 드립니다.

논리를 생각하고, 구현에서 막혀서 고민 중 강의의 코드를 보다가 구지 main과 dfs 둘 다 visited = 1 의 과정을 적어야 하는지에 대해 의문이 듭니다. 위의 제가 올려둔 코드처럼 할 경우 문제가 있는지 알고 싶습니다!

답변 1

1

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

안녕하세요. ㅎㅎ

void dfs(int y, int x, vector<pair<int,int>>&v)
{
    // 열렸으면, dfs를 실행 한 경우, 평균을 내야하는데..
    
    visited[y][x]=1;

여기에 visited를 걸었는데

                if(!visited[i][j])
                {
                    v.clear();
                    visited[i][j] = 1;
                    v.push_back({i,j});

이렇게도 걸었다.

이부분 말씀하시는 거죠?

네 로직상은 문제가 없습니다. 왜냐면

        if(visited[ny][nx]) continue;

ny, nx를 기반으로 continue가 수행되기 때문에 y, x에 관해 중복으로 처리했어도 괜찮습니다.

 

다만,

이렇게 하시는게 더 깔끔할 거같아요.

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

int a[54][54], visited[54][54];
int n, l, r, ret, cnt;
const int dy[]={-1,0,1,0}, dx[]={0,1,0,-1};
int sum;
vector<pair<int,int>>v;

void dfs(int y, int x, vector<pair<int,int>>&v)
{
    // 열렸으면, dfs를 실행 한 경우, 평균을 내야하는데..
     
    for(int i = 0 ; i < 4 ;i++)
    {
        int ny = y + dy[i];
        int nx = x + dx[i];
        
        int tmp_cha = abs(a[y][x] - a[ny][nx]);
        
        if(ny < 0 || nx < 0 || n <= ny || n <= nx)  continue;
        if(visited[ny][nx]) continue;
        if(tmp_cha < l || r < tmp_cha)   continue;
        
        // 여기다가 하는데..
        // 한 바퀴가 다 돈 다음에 평균 내야 하잖아..
        // 여기다가 bool type을 둬서, 새로운 함수 만들어서 평균 내야하나??
         
        v.push_back({ny,nx});
        sum += a[ny][nx];
    	visited[ny][nx]=1;
        dfs(ny,nx,v);
    }
}

int main(void)
{
    cin >> n >> l >> r;
    
    for(int i = 0 ; i < n ; i++)
    {
        for(int j = 0 ; j < n ; j++)
        {
            cin >> a[i][j]; // i는 y , j는 x
        }
    }
    
    // 논리는 엇비슷하게 생각해냈는데.. 
    // 이 밑의 것은 아예 구현 방법을 떠올리지 못했어..
    // 구현은 다시 한 번 연습해볼 것!
    
    while(1){   // 끝날때까지 dfs 반복이니까, while이 필요하구나..
        bool flag = 0 ; // 이걸로 dfs 여부 확인이구나..
        // fill(visited[0][0],0,sizeof(visited));
        fill(&visited[0][0],&visited[0][0]+54*54,0);
        for(int i = 0 ; i < n ; i++)
        {
            for (int j = 0 ; j < n ; j++)
            {
                if(!visited[i][j])
                {
                    v.clear(); 
                    v.push_back({i,j});
                    sum = a[i][j];
                    visited[i][j] = 1;
                    dfs(i,j,v);
                    if(v.size()==1) continue;
                    for(pair<int,int> b : v)
                    {
                        a[b.first][b.second] = sum / v.size();
                        flag = 1;
                    }
                }
            }
        }
        if(!flag) break;
        cnt++;
    }
    cout << cnt << '\n';
    return 0;
}

/*
처음에 n l r  입력 받아.
n * n 만큼 입력 받고
인구 차이가 l이상 r이하인 곳은 국경선을 열어서 서로 평균 낼 수 있어.
열린 것은 열린 곳까지의 평균을 나눠 갖는다.
국경선을 처음에 다 열고, 그 다음에 한번에 해야할 듯?
- 한번 열은 것을 재개방 불가능 -> visited 써야하는데?

전체 탐색 dfs인가? - 시간복잡도 봅시다. 50 * 50 || 1<= <= 100
2500C2 인 듯?

하루에 한번만 열리는 것, 이거 fill이나 memset으로 visited 초기화 필요
dfs해도 되겠다.

평범한 dfs에다가 l이상 r 이하 이 조건만 넣으면 될 듯?


connected component..?
*/

 

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

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

감사합니다.

강사 큰돌 올림.

kimseunghwan7777님의 프로필 이미지
kimseunghwan7777

작성한 질문수

질문하기