unagi11
이국의 보조기억장치
unagi11
전체 방문자
오늘
어제
  • 전체 글 (35)
    • Technology (28)
      • Algorithm Theory (10)
      • Problem Solving (14)
      • Unreal (1)
      • Unity (1)
      • Cocos2d (0)
      • etc (2)
    • Develop (5)
      • Dungeon-Chess (0)
      • Past Projects (3)
      • etc (2)
    • Daily (2)

블로그 메뉴

  • 깃허브
  • 프로필

인기 글

최근 글

hELLO · Designed By 정상우.
unagi11

이국의 보조기억장치

Technology/Problem Solving

[BOJ] 16946번: 벽 부수고 이동하기 4

2022. 5. 5. 13:45
 

16946번: 벽 부수고 이동하기 4

N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 한 칸에서 다른 칸으로 이동하려면, 두 칸이 인접해야 한다. 두 칸이

www.acmicpc.net

제한 조건
- 시간 제한 : 2s
- 공간 제한 : 512MB

풀이 사용
- 사용 언어 : C++17
- 사용 시간 : 184ms
- 사용 공간 : 25992KB

풀이 설명
- Connected Component를 그래프 순회(BFS)를 통해 분류
- Connected Component의 크기는 따로 리스트에 기록
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>

using namespace std;

int rows, cols;

vector<vector<char>> matrix;  // 초기 행렬구조
vector<vector<bool>> visited; // cc 생성 기록
vector<vector<int>> cc;       // connected component
vector<int> cc_size;          // cc 크기기록

void initializer()
{
    matrix = vector<vector<char>>(rows, vector<char>(cols));
    visited = vector<vector<bool>>(rows, vector<bool>(cols, false));
    cc = vector<vector<int>>(rows, vector<int>(cols, 0));
    cc_size = vector<int>(1, 0);
}

// (y, x)부터 bfs순회하여 이어진 모든 점을 n으로 바꾼다.
void bfs(int y, int x, int n)
{
    // 범위를 벗어나면 cc_size를 늘리거나 bfs를 진행하지 않는다.
    if (y < 0 || y >= rows || x < 0 || x >= cols)
        return;

    // 이미 방문한, 혹은 벽인 노드라면 순회하지 않는다.
    if (visited[y][x] == true || matrix[y][x] == 1)
        return;

    // 공백이라면, 해당 n번째 공백 덩어리의 cc_size를 늘리고 한번더 bfs 순회확장한다.
    visited[y][x] = true;
    cc[y][x] = n;
    cc_size[n]++;

    // 상하좌우 탐색.
    bfs(y - 1, x, n);
    bfs(y + 1, x, n);
    bfs(y, x - 1, n);
    bfs(y, x + 1, n);
}

// 모든 매트릭스공간을 순회하며, connected component 처리를 해준다.
void initCC()
{
    int cc_index = 1;

    for (int y = 0; y < rows; y++)
        for (int x = 0; x < cols; x++)
            if (visited[y][x] == false && matrix[y][x] == 0)
            {
                cc_size.push_back(0);
                bfs(y, x, cc_index);
                cc_index++;
            }
}

// 범위를 넘어가는 cc를 0으로 받는 함수.
int getCC(int y, int x)
{
    if (y < 0 || y >= rows || x < 0 || x >= cols)
        return 0;
    else
        return cc[y][x];
}

int main(int argc, char const *argv[])
{
    scanf("%d %d\n", &rows, &cols);

    initializer();

    for (int y = 0; y < rows; y++)
    {
        for (int x = 0; x < cols; x++)
        {
            scanf("%c", &matrix[y][x]);
            matrix[y][x] = matrix[y][x] - '0';
        }
        scanf("\n");
    }

    initCC();

    for (int y = 0; y < rows; y++)
    {
        for (int x = 0; x < cols; x++)
        {
            if (matrix[y][x] == 0)
                printf("%d", 0);
            else
            {
                set<int> s;
                s.insert(getCC(y - 1, x));
                s.insert(getCC(y + 1, x));
                s.insert(getCC(y, x - 1));
                s.insert(getCC(y, x + 1));

                int temp = 1;
                set<int>::iterator iter;
                for (iter = s.begin(); iter != s.end(); iter++)
                    temp += cc_size[*iter];

                printf("%d", temp % 10);
            }
        }
        printf("\n");
    }

    return 0;
}

 

 
 
저작자표시 변경금지 (새창열림)
    'Technology/Problem Solving' 카테고리의 다른 글
    • [BOJ] 1738번: 골목길
    • [BOJ] 2152번: 여행 계획 세우기
    • [BOJ] 9240번: 로버트 후드
    • [BOJ] 7620번: 편집 거리
    unagi11
    unagi11
    개발하고 기록하자

    티스토리툴바