강의

멘토링

로드맵

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

Blaire님의 프로필 이미지
Blaire

작성한 질문수

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

2-P

84.2-P 코드 관련 질문

작성

·

10

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;
    }

답변

답변을 기다리고 있는 질문이에요
첫번째 답변을 남겨보세요!
Blaire님의 프로필 이미지
Blaire

작성한 질문수

질문하기