inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

2-P

84.2-P 코드 관련 질문

46

Blaire

작성한 질문수 17

0

안녕하세요 선생님

해당 문제에 대해 선생님의 코드와

제가 스스로 풀어서 맞힌 코드에 대해 질문 있어 작성합니다.

  1. 먼저 선생님 코드에서 선생님의 로직을 정리하면 아래와 같이 된다고 생각하는데 맞는지 여쭤봅니다.


    (선생님 코드 링크) http://boj.kr/2812582f10eb41dfa63761279266e42f

     

    /*
    선생님 로직에서>
    !visited[][] && !a[][] => 안전영역
    !visited[][] && a[][]==1 => 벽이 있어서 접근 불가 영역 (continue로 처리, 즉 벽이 있는 영역은 visited[][]가 1로 set될 수 없음)
    !visited[][] && a[][]==2 => 원래부터 바이러스가 있는 영역 (visited[][]==1로 set)
    visited[][] && !a[][] => 바이러스가 퍼지는 영역(visited[][]==1로 set)
    visited[][] && a[][]==1 => 이런 경우는 발생하지 않음
    visited[][] && a[][]==2 => 원래부터 바이러스가 있는 영역인데 이미 방문한 영역(cotinue로 처리)
    */
  2. 제가 스스로 풀어서 맞춘 코드에 대해 논리적으로 완벽한게 맞는지 코드 리뷰를 부탁드립니다.


    제가 생각했을 때 저는 visited 배열과 a배열을 사용하신 선생님과 달리 g배열 하나를 사용하여 g배열의 값(0,1,2)에 따라 각 영역을 구분하여 풀었는데요. 백준에서 채점한 결과 문제를 맞췄다고 나왔는데 혹 제가 불필요한 부분을 중복 체크하는 논리적인 오류가 있는지 헷갈려 선생님께 질문드립니다.


    (제 코드 링크) http://boj.kr/f2b1836ef32f4c1b8c06ad497201d99b


    제가 백준 제출시에는 주석을 다 빼고 코드를 붙여 넣어 코드 파악에 더 용이하도록 아래는 주석을 붙인 코드도 첨부합니다.
    감사합니다.

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n, m; // 세로, 가로 
    int safe_size; // 안전 영역 크기 
    
    int g[10][10]; 
    vector<pair<int, int>> combi;
    
    const int dy[] = {-1, 0, 1, 0};
    const int dx[] = {0, 1, 0, -1};
    
    void virus_spread(int gp[][10], int a, int b){
        for(int i=0; i<4; i++){
            int ny = a + dy[i];
            int nx = b + dx[i];
            // graph 범위를 초과할 때
            if(ny<0 || nx<0 || ny>=n || nx>=m) continue;
            // gp[ny][nx]==1 벽이거나 gp[ny][nx]==2 이미 바이러스가 있을 때
            if(gp[ny][nx]) continue;
            // gp[ny][nx]==0 빈 칸 일때
            gp[ny][nx] = 2; 
            virus_spread(gp, ny, nx);
        }
    }
    
    int main(){
        ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    
        cin >> n >> m; 
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                cin >> g[i][j];
                // 벽을 세울 수 있는 후보 좌표 따로 저장하기 
                if (!g[i][j]) combi.push_back({i, j});
            } 
        }
    
        size_t c = combi.size();
        for(size_t i=0; i<c; i++){
            for(size_t j=i+1; j<c; j++){
                for(size_t k=j+1; k<c; k++){
                    // cout >> i >> " " >> j >> " " >> k >> "\n";
                    pair<int, int> p1 = combi[i];
                    pair<int, int> p2 = combi[j];
                    pair<int, int> p3 = combi[k];
                    
                    // 3개의 벽 세우기 
                    g[p1.first][p1.second] = 1;
                    g[p2.first][p2.second] = 1;
                    g[p3.first][p3.second] = 1;
    
                    // 바이러스 퍼뜨리기
                    int dup_g[10][10];
                    copy(&g[0][0], &g[0][0]+100, &dup_g[0][0]);
    
                    for(int a=0; a<n; a++){
                        for(int b=0; b<m; b++){
                            // 바이러스가 있는 칸이면 spread virus 
                            if(dup_g[a][b]==2) virus_spread(dup_g, a, b);
                        }
                    }
                   
                    // 안전영역크기 카운트 
                    int count_safe=0;
                    for(int a=0; a<n; a++){
                        for(int b=0; b<m; b++){
                            if(!dup_g[a][b]) count_safe++;
                        }
                    }
                    // 최대안전영역크기 갱신
                    safe_size = max(safe_size, count_safe);
    
                    // graph 초기화
                    g[p1.first][p1.second] = 0;
                    g[p2.first][p2.second] = 0;
                    g[p3.first][p3.second] = 0;
                }
            }
        }
        cout << safe_size << "\n";
        return 0;
    }

c++ 코딩-테스트

답변 1

1

큰돌

안녕하세요 ㅎㅎ

너무 잘하셨네요.

벽후보 리스트 combi로 정리 -> 해당 경우의 수에 대해서 원복이나 바이러스 퍼지는 것 모두 잘하셨습니다.

 

필요한 부분을 중복 체크하는

-> 없습니다.

 

 


 

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

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

감사합니다.

강사 큰돌 올림.

0

Blaire

감사합니다 선생님

혹시 1번 질문인

선생님 코드에 대해 제가 정리한 로직 정리도 맞는지 여쭤봅니다!

0

큰돌

안녕하세요 ㅎㅎ

코멘트 달았습니다.

/*
선생님 로직에서>
!visited[][] && !a[][] => 안전영역 : 넵
!visited[][] && a[][]==1 => 벽이 있어서 접근 불가 영역 (continue로 처리, 즉 벽이 있는 영역은 visited[][]가 1로 set될 수 없음) 넵
!visited[][] && a[][]==2 => 원래부터 바이러스가 있는 영역 (visited[][]==1로 set) : 넵
visited[][] && !a[][] => 바이러스가 퍼지는 영역(visited[][]==1로 set) : 네
visited[][] && a[][]==1 => 이런 경우는 발생하지 않음 넵
visited[][] && a[][]==2 => 원래부터 바이러스가 있는 영역인데 이미 방문한 영역(cotinue로 처리) : 바이러스가 퍼진 지역입니다. 
*/

 

5-B

0

4

1

4 - A

0

30

2

코딩살구클럽 입장이 안됩니다

0

78

2

4-F 경우의 수 질문입니다.

0

34

2

코딩살구클럽 가입이 안됩니다.

0

81

2

살구 클럽에 대한 질문있습ㄴ디ㅏ

0

61

1

교안 158페이지 문의드립니다

0

46

2

코딩살구클럽 관련 건의사항

0

119

1

코살에 19942 다이어트 문제에 N의 범위가 빠져있슴니다

0

45

1

진행 방법 질문드립니다!

0

81

2

2-I) 왜 이 문제가 그래프이론 카테고리에 있는지 잘 모르겠습니다.

0

64

2

2주차 개념#12 트리 순회

0

33

2

백준사이트가 종료된다고 합니다.

0

318

2

백준 서비스 종료

9

953

1

sk 하이닉스 코테 대비

0

388

2

3-G 최댓값 질문

0

54

1

모듈러 연산 값이 10이 아닌 경우도 있지 않나요?

0

84

2

3-I 코드 질문드립니다.

0

66

2

3-N 질문 있습니다.

0

68

2

학습방법

0

105

2

4-H 질문 있습니다 (코드 리뷰)

0

69

2

코딩테스트 어디까지 준비해야 하는지 질문이 있습니다.

0

186

2

2-O 반례가 무엇일지 어떤 부분이 틀렸는지 잘 모르겠습니다.

0

73

2

2주차 개념 #4-2. 인접행렬 질문있습니다.

0

66

2