본문 바로가기
코테

[BOJ] 숫자판 점프

by arirang_ 2024. 8. 7.

Link: https://www.acmicpc.net/problem/2210

Level : S2

유형 : 완전탐색, dfs


📌 문제 탐색하기

입력 : 5X5 배열 각 요소 값

 

이 문제는 임의의 위치에서 인접해있는 4 방향으로 5번 움직이는 문제다.

따라서 5*5 총 25개의 인덱스에서 4 방향으로 탐색해야 한다.

 

시간 복잡도를 생각해보면 

임의의 점 선택 : 5*5

선택된 점에서 4 방향으로 5번 움직이는 경우의 수 : 4*4*4*4*4

 

시간복잡도는 O(n^2)이지만 연산 횟수는 25,600번 밖에 되지 않는다.

 

따라서 이 문제는 '완전탐색'으로 진행한다.

 

📌  코드 설계하기

1. 5*5 배열의 값을 입력으로 받는다.

2. 반복문을 돌면서 임의의 점을 택하고 그 점에서 대해 dfs 함수를 실행한다.

3. 재귀를 이용하여 cnt가 5번이 될 때까지 4방향으로 이동하며 나올 수 있는 6자리 수를 만든다.

4. cnt가 5가 되면 map에 만들어진 숫자를 넣고, 함수를 종료한다.

이때 map을 사용하는 이유는 중복된 숫자를 카운트하지 않기 위해서이다.

5. map의 size를 출력하면 만들어진 숫자의 총 갯수가 출력된다.

 

📌  시도 회차 수정 사항

코드를 설계하고 작성한 뒤 돌렸을 때 segmentation fault 오류가 떴다.

이유는 2가지였다.

첫번째는 dfs를 실행할 때 dfs 안에서 반복문을 통해 4가지 방향으로 탐색하는데,

이때 탐색 범위에 대한 제한을 두지 않아 오류가 발생했다.

두번째는 재귀가 종료되면 cnt와 만들어진 수인 s 모두 이전 상태로 돌려야 하는데 cnt를 이전 상태로 돌리지 않아 오류가 발생했다.

 

segmentation fault 오류가 뜨면 배열 범위를 벗어나는 접근을 하는지 꼭! 체크를 해봐야겠다.

 

📌 정답 코드

#include <iostream>
#include <string>
#include <map>
using namespace std;

int arr[7][7], cnt, ret, ny, nx;
string s;
map<string, int> mp;

int dy[]={-1, 0, 1, 0};
int dx[]={0, 1, 0, -1};

void dfs(int y, int x, int cnt){
    if(cnt == 5){
        mp[s]++;   //map에 넣어서 중복 경우 방지
        return;
    }

    for(int i=0; i<4; i++){
        ny = y + dy[i];
        nx = x + dx[i];

        if(ny<0 || ny>=5 || nx <0 || nx>=5 ) continue;

        s += to_string(arr[ny][nx]);
        dfs(ny, nx, ++cnt); 
        s.pop_back();
        cnt-=1;
    }
}

int main(){

    for(int i=0; i<5; i++){
        for(int j=0; j<5; j++){
            cin >> arr[i][j];
        }
    }

    for(int i=0; i<5; i++){
        for(int j=0; j<5; j++){
            cnt = 0;
            s = to_string(arr[i][j]);
            dfs(i, j, cnt);
        }
    }

    cout << mp.size() << "\n";

    return 0;
}

'코테' 카테고리의 다른 글

[BOJ] 물통  (0) 2024.08.12
[BOJ] 단지번호붙이기  (0) 2024.08.11
[BOJ] 부분수열의 합  (1) 2024.08.06
[BOJ] 두 스티커  (0) 2024.08.05
백준 2178번 - 미로 탐색  (0) 2023.11.08