-
[Python][C++] 21736번 헌내기는 친구가 필요해Algorithm/Baekjoon 2024. 9. 15. 12:30
문제
https://www.acmicpc.net/problem/21736
코드
1. Python
import sys from collections import deque input = sys.stdin.readline # 빠른 입력을 위해 sys.stdin.readline 사용 # BFS(너비 우선 탐색) 함수 정의 def bfs(x, y): # 상하좌우 탐색을 위한 방향 벡터 dx = [-1, 1, 0, 0] dy = [0, 0, -1, 1] # 방문 여부를 기록하는 2차원 리스트 visited = [[0] * m for _ in range(n)] cnt = 0 # 만날 수 있는 사람의 수를 저장하는 변수 # BFS를 위한 큐 초기화 및 시작 위치 삽입 q = deque() q.append([x, y]) visited[x][y] = 1 # 시작 위치 방문 처리 # 큐가 빌 때까지 탐색 while q: x, y = q.popleft() # 상하좌우 네 방향 탐색 for i in range(4): nx, ny = x + dx[i], y + dy[i] # 보드의 범위를 벗어나지 않고, 방문하지 않은 곳이고, 벽('X')이 아닌 경우 if 0 <= nx < n and 0 <= ny < m: if board[nx][ny] != 'X' and not visited[nx][ny]: visited[nx][ny] = 1 # 방문 처리 q.append([nx, ny]) # 다음 위치 큐에 삽입 # 사람이 있는 위치('P')일 경우 카운트 증가 if board[nx][ny] == 'P': cnt += 1 return cnt # 만날 수 있는 사람의 수 반환 # 보드의 크기(n: 행, m: 열) 입력 n, m = map(int, input().split()) board = [input().rstrip() for _ in range(n)] # 보드 상태 입력 # 시작 위치('I')를 찾음 for i in range(n): for j in range(m): if board[i][j] == 'I': start_x, start_y = i, j # 시작 위치 기록 break # BFS 수행하여 만날 수 있는 사람의 수 계산 ans = bfs(start_x, start_y) # 결과 출력: 만날 수 있는 사람이 없으면 "TT" 출력, 그렇지 않으면 만난 사람 수 출력 print(ans if ans else "TT")2. C++
#include <iostream> #include <vector> #include <queue> using namespace std; // BFS 함수: 시작 위치 (x, y)에서 보드를 탐색하며 'P'의 개수를 센다 int bfs(int x, int y, int n, int m, const vector<string> board) { int dx[] = { -1, 1, 0, 0 }; // 상하좌우 이동을 위한 배열 int dy[] = { 0, 0, -1, 1 }; // 상하좌우 이동을 위한 배열 queue<pair<int, int>> q; // BFS를 위한 큐 vector<vector<int>> visited(n, vector<int>(m)); // 방문 여부를 체크할 배열 int cnt = 0; // 'P'의 개수를 세는 변수 q.push(make_pair(x, y)); // 시작 위치를 큐에 넣음 visited[x][y] = 1; // 시작 위치 방문 처리 while (!q.empty()) { x = q.front().first; // 현재 위치의 x 좌표 y = q.front().second; // 현재 위치의 y 좌표 q.pop(); if (board[x][y] == 'P') // 현재 위치에 'P'가 있으면 카운트 증가 cnt++; // 상하좌우로 이동 for (int i = 0; i < 4; i++) { int nx = x + dx[i]; // 새로운 x 좌표 int ny = y + dy[i]; // 새로운 y 좌표 // 보드의 범위를 벗어나면 무시 if (0 > nx || nx >= n || 0 > ny || ny >= m) continue; // 'X'가 아니고 방문하지 않은 위치만 탐색 if (board[nx][ny] != 'X' && !visited[nx][ny]) { q.push(make_pair(nx, ny)); // 새로운 위치를 큐에 추가 visited[nx][ny] = 1; // 방문 처리 } } } return cnt; // 'P'의 개수 반환 } int main() { int n, m; cin >> n >> m; // 보드의 크기 n x m 입력 vector<string> board(n); // 보드를 저장할 벡터 int sx = -1, sy = -1; // 'I'의 위치를 저장할 변수 // 보드 입력 for (int i = 0; i < n; i++) { cin >> board[i]; // 각 행의 문자열 입력 // 'I'의 위치 찾기 for (int j = 0; j < m; j++) { if (board[i][j] == 'I') { sx = i; // 시작 위치의 x 좌표 sy = j; // 시작 위치의 y 좌표 } } } // BFS를 수행하여 'P'의 개수 반환 int ret = bfs(sx, sy, n, m, board); // 결과 출력 if (ret) cout << ret; else cout << "TT"; // 'P'를 찾지 못한 경우 "TT" 출력 return 0; }풀이
- 그래프 탐색:
- 캠퍼스를 2차원 격자로 보고, 도연이가 이동할 수 있는 모든 영역을 탐색해야 한다.
- '도연'이의 위치에서 시작하여 상하좌우로 이동하며 'O'로 표시된 빈 공간을 탐색한다.
- 이동하는 동안 만나는 친구('P')의 수를 세어 나간다.
- 탐색 조건:
- 도연이는 빈 공간('O')과 친구가 있는 칸('P')만 이동할 수 있다.
- 벽('#')은 이동이 불가능하며, 이를 통해 탐색을 제한한다.
- 탐색을 시작하기 위해 먼저 'I'의 위치(도연이의 위치)를 찾는다.
- BFS 사용:
- 'I'의 위치에서 BFS나 DFS를 시작하여, 방문할 수 있는 모든 칸을 탐색한다.
- 탐색하면서 만나는 친구의 수를 카운트한다.
- 이미 방문한 칸은 다시 방문하지 않도록 표시하여 중복 탐색을 방지한다.
- 경계 조건:
- 격자 밖으로 나가지 않도록 경계를 검사한다.
- 상하좌우로만 이동할 수 있으므로, 각 위치에서 네 방향(위, 아래, 왼쪽, 오른쪽)으로 이동을 시도한다.
- 결과 처리:
- BFS 또는 DFS가 종료된 후, 만난 친구의 수를 출력한다.
- 만약 친구를 만나지 못하면 TT를 출력한다.
'Algorithm > Baekjoon' 카테고리의 다른 글
[Python][C++] 1043번 거짓말 (0) 2024.09.17 [C++] 30804번 과일 탕후루 (0) 2024.09.15 [Python][C++] 18870번 좌표 압축 (0) 2024.09.14 [Python][C++] 18111번 마인크래프트 (2) 2024.09.12 [Python][C++] 17626번 Four Squares (0) 2024.09.11 - 그래프 탐색: