[백준] 16724번 피리 부는 사나이 (C++)

2025. 8. 19. 18:23·Algorithm
728x90

https://www.acmicpc.net/problem/16724

 

 

이 문제는 격자 그래프가 주어졌을때 각 칸마다 어떤 행동을 취할지 알파벳으로 주어지고 행동을 취했을때 이미 방문했던(사이클)이 발생한 경우

그 사이클은 안전지대를 하나를 놔야하며 이때 최소한의 안전지대의 개수를 출력하는 문제이다.

 

사이클을 판별하기 위해선 bool 방문배열을 사용하여 이전에 방문했던 경우 사이클로 판단하여 개수를 하나씩 늘리면 가능하다

하지만 이런 경우가 있을 수 있다

 

만약 사이클이 존재하는 경로가 있고 이전에 방문하지 않았던 경로가 사이클에 진입하는 경우가 있을 수 있다.

이 경우에는 같은 사이클이지만 서로 다른 사이클로 판단한다.

 

따라서 int형 방문배열을 사용하여 처음엔 -1로 초기화 시켰으며

 

이전에 cnt값을 1로 생성하여 dfs호출이 끝났을때 값을 하나씩 증가시켜주었다.

 

위와 같은 경우는 dfs함수 내에서 조건문을 적절히 잘 사용하면 같은 사이클인지 판별할 수 있다.

 

 

정답코드

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
#define endl "\n"
#define MAX 1e9

struct coordinate {
    int x;
    string s;
    vector<int> v;
};

int dx[] = {-1, 0, 1, 0, 1, -1, -1, 1};
int dy[] = {0, 1, 0, -1, -1, 1, -1, 1};
int N, M;
char graph[1001][1001];
int dp[1001][1001];
int cnt;

int dfs(int x, int y) {
    if(dp[x][y] != -1) return dp[x][y];
    dp[x][y] = cnt;

    if(graph[x][y] == 'U') {
        dp[x][y] = dfs(x-1, y);
    }
    else if(graph[x][y] == 'D') {
        dp[x][y] = dfs(x+1, y);
    }
    else if(graph[x][y] == 'L') {
       dp[x][y] = dfs(x, y-1);
    }
    else dp[x][y] = dfs(x, y+1);

    return dp[x][y];
}

void solve() {

    for(int i = 0; i < N; i++) {
        for(int j = 0; j < M; j++) {
            if(dp[i][j] == -1) {
                dfs(i, j);
                cnt++;
            }
        }
    }

    set<int> st;

    for(int i = 0; i < N; i++) {
        for(int j = 0; j < M; j++) {
            st.insert(dp[i][j]);
        }
    }

    cout << st.size();

    // for(int i = 0; i < N; i++) {
    //     for(int j = 0; j < M; j++) {
    //         cout << dp[i][j] << " ";
    //     }
    //     cout << endl;
    // }

    // cout << cnt;
}

void Init() {
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < M; j++) {
            dp[i][j] = -1;
        }
    }
}

void input() {
    cin >> N >> M;

    for(int i = 0; i < N; i++) {
        for(int j = 0; j < M; j++) {
            cin >> graph[i][j];
        }
    }

    Init();
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    input();
    solve();

    return 0;
}

 

 

회고록

내가 짠 코드는 별로 좋지 않은 코드인것 같다

이중 for문에서 방문하지 않았던 칸에 대해서 dfs를 호출하고 끝난 경우 바로 답이 나올거 같은데

 

현재 내 코드에서는 한번더 격자를 탐색하여 set에 넣어주는 과정이 존재한다.

재귀쪽에서 많이 햇갈려서 시간이 많이 허비가되었다

728x90
저작자표시 (새창열림)

'Algorithm' 카테고리의 다른 글

[백준] 11559번 Puyo Puyo (C++)  (0) 2025.08.21
[백준] 16562번 친구비 (C++)  (0) 2025.08.20
[백준] 11497번 통나무 건너뛰기 (C++)  (0) 2025.08.18
[백준] 10775번 공항 (C++)  (0) 2025.08.17
[백준] 18234번 당근 훔쳐 먹기 (C++)  (0) 2025.08.16
'Algorithm' 카테고리의 다른 글
  • [백준] 11559번 Puyo Puyo (C++)
  • [백준] 16562번 친구비 (C++)
  • [백준] 11497번 통나무 건너뛰기 (C++)
  • [백준] 10775번 공항 (C++)
쿨쿨.
쿨쿨.
  • 쿨쿨.
    All of the life
    쿨쿨.
  • 전체
    오늘
    어제
    • 분류 전체보기 (286) N
      • Programming (53) N
        • C, C++ (18)
        • Python (6)
        • Java (1)
        • HTML,CSS,JS (3)
        • SQL(DB) (13)
        • SpringBoot (9) N
        • Android (2)
        • CI,CD (1)
      • Algorithm (173)
        • Review (4)
      • Security (14)
        • WebHacking (3)
        • Websecurity (11)
      • OS (19)
        • Linux (12)
        • Mac os (2)
      • 머신러닝 (1)
      • CS(Computer Science) (12)
        • 컴퓨터 네트워크 (3)
        • 컴퓨터 구조 (1)
        • 인공지능 (8)
      • Docker (2) N
      • Dev Book Review (3)
        • Clean Code (1)
        • Effective Java (0)
        • Real MySQL (2)
      • SWM (1)
      • Review (6)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    구현
    wargame
    그리디
    이분탐색
    DP
    DFS
    WebSecurity
    다이나믹 프로그래밍
    BFS
    투포인터
    비트마스킹
    브루트포스
    다익스트라
    재귀
    c언어
    코딩
    Leviathan
    백준
    트리
    시뮬레이션
    우선순위큐
    깊이우선탐색
    Bandit
    그래프 이론
    에라토스테네스의 체
    백트래킹
    우선순위 큐
    linux
    정렬
    누적합
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.6
쿨쿨.
[백준] 16724번 피리 부는 사나이 (C++)
상단으로

티스토리툴바