Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • BFS
  • DFS
  • 백트래킹
  • 프로그래머스
  • 다이나믹 프로그래밍
  • django
  • docker
  • Kubernetes
  • Network
  • boj

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

[백준 16929] Two Dots C++
Algorithm/BOJ

[백준 16929] Two Dots C++

2021. 5. 27. 22:33
 

16929번: Two Dots

첫째 줄에 게임판의 크기 N, M이 주어진다. 둘째 줄부터 N개의 줄에 게임판의 상태가 주어진다. 게임판은 모두 점으로 가득차 있고, 게임판의 상태는 점의 색을 의미한다. 점의 색은 알파벳 대문

www.acmicpc.net

DFS


1. 문제해결 아이디어

DFS를 통해서 사이클을 찾는 문제이다.

시작 알파벳과 같은 칸만 이동하며 시작 좌표에 다시 돌아올 때까지 or 돌아오지 못할 때까지 dfs 를 돌린다.

하나의 dfs루프에서 방문한 점을 backtracking 하지 않고 방문처리 기록을 남겨둔다.


2. 코드

<+27> : dfs를 돌면서 방문을 했거나

시작점으로 지목된 점에 방문을 한 경우 + 현재 점이 시작점이 아닌경우 (시작하자마자 return 되는것 방지)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
#include <cstring>
 
using namespace std;
 
int N, M;
char Map[51][51];
int dr[4] = {0, 0, 1, -1}, dc[4] = {1, -1, 0, 0};
bool visited[51][51], visited_dfs[51][51];
 
void dfs(char now, int sr, int sc, int d, int r, int c){
    /*
        시작점에 다시 도착하거나 이동할 곳이 없을 때까지 탐색
    */
    
    
    if(d >= 4 && (sr == r && sc == c)){
        /*
            4개 이상의 점으로 구성된 사이클이거나 현재 좌표가 시작 좌표와 같으면
            사이클을 찾았으므로 프로그램 종료
        */
        cout << "Yes";
        exit(0);
    }
    
    
    if(visited_dfs[r][c] || (visited[r][c] && d)) return;
    visited_dfs[r][c] = true;
    
    for(int i = 0; i < 4; i++){
        int nr = r + dr[i];
        int nc = c + dc[i];
        char next = Map[nr][nc];
        
        // 맵을 벗어나거나 다음 문자가 시작 문자와 다를경우 탐색하지 않는다
        if(nr < 0 || nc < 0 || nr >= N || nc >= M || next != now) continue;
        else dfs(next, sr, sc, d+1, nr, nc);
    }
}
 
void solve(){
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            /*
                시작점으로 지목된 점은 다시 탐색해볼 필요가 없다
                이미 해당 점으로 부터 dfs 탐색을 완료했기 때문에 다른점을 거쳐서 왔다고 하여 다시 dfs를 한다는건  
                중복이 매우 많아지게 된다
            */
            visited[i][j] = true;
            char now = Map[i][j];
            memset(visited_dfs, 0, sizeof(visited_dfs));
            dfs(now, i, j, 0, i, j);
        }
    }
    cout << "No";
}
 
void input(){
    string str;
    
    cin >> N >> M;
    for(int i = 0; i < N; i++){
        cin >> str;
        for(int j = 0; j < M; j++){
            Map[i][j] = str[j];
        }
    }
}
 
int main(){
    input();
    solve();
    
    return 0;
}
 
Colored by Color Scripter
cs

풀고나서 다른 사람들의 코드를 봤는데

내가 너무 비효율적으로 짰다..

기록 배열을 하나만 사용해도되는데.. solve함수의 2중 for문에서 매번 memset 안해줘도 됐는데..

'Algorithm > BOJ' 카테고리의 다른 글

[백준 2011] 암호코드 C++  (0) 2021.06.01
[백준 2143] 두 배열의 합 C++  (2) 2021.05.30
[백준 1309] 동물원 C++  (0) 2021.05.26
[백준 17298 17299] 오큰수 , 오등큰수 C++  (0) 2021.05.25
[백준 1644] 소수의 연속합 C++  (0) 2021.05.24
    'Algorithm/BOJ' 카테고리의 다른 글
    • [백준 2011] 암호코드 C++
    • [백준 2143] 두 배열의 합 C++
    • [백준 1309] 동물원 C++
    • [백준 17298 17299] 오큰수 , 오등큰수 C++

    티스토리툴바