diff --git "a/08_DFS_BFS/\353\217\204\354\240\204/10026.cpp" "b/08_DFS_BFS/\353\217\204\354\240\204/10026.cpp" deleted file mode 100644 index a2b73d8..0000000 --- "a/08_DFS_BFS/\353\217\204\354\240\204/10026.cpp" +++ /dev/null @@ -1,84 +0,0 @@ -// 적록색약 x: 빨, 초, 파 구분 -// 적록색약 o: 빨=초, 파 구분 -// 구역 탐색에 DFS 이용. - -#include -#include -#include -using namespace std; - -const int MAX = 100; -char grid[MAX][MAX]; // 원본 그리드 -bool visited[MAX][MAX]; // 방문 여부 체크 -int dx[] = {-1, 1, 0, 0}; // 상하좌우 탐색을 위한 방향 벡터 -int dy[] = {0, 0, -1, 1}; -int n; - -// DFS로 구역을 탐색하는 함수 -void dfs(int x, int y, char color) { - visited[x][y] = true; - - for (int i = 0; i < 4; i++) { - int nx = x + dx[i]; - int ny = y + dy[i]; - - // 지도 범위를 벗어나지 않고, 같은 색상인 경우 DFS 계속 진행 - if (nx >= 0 && ny >= 0 && nx < n && ny < n && !visited[nx][ny] && grid[nx][ny] == color) { - dfs(nx, ny, color); - } - } -} - -// 적록색약 처리: R -> G 변환 -void convert() { - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - if (grid[i][j] == 'R') { - grid[i][j] = 'G'; - } - } - } -} - -int main() { - ios::sync_with_stdio(false); - cin.tie(0); - - // 입력 받기 - cin >> n; - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - cin >> grid[i][j]; - } - } - - // 적록색약 x 경우 - int normal_count = 0; - fill(&visited[0][0], &visited[0][0] + MAX * MAX, false); - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - if (!visited[i][j]) { - dfs(i, j, grid[i][j]); - normal_count++; - } - } - } - - // 적록색약 o 경우 - int color_blind_count = 0; - convert(); // 적록색약 처리를 위해 변환 - fill(&visited[0][0], &visited[0][0] + MAX * MAX, false); - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - if (!visited[i][j]) { - dfs(i, j, grid[i][j]); - color_blind_count++; - } - } - } - - // 결과 출력 - cout << normal_count << ' ' << color_blind_count << '\n'; - - return 0; -} diff --git "a/08_DFS_BFS/\353\217\204\354\240\204/14502.cpp" "b/08_DFS_BFS/\353\217\204\354\240\204/14502.cpp" deleted file mode 100644 index dd2ec49..0000000 --- "a/08_DFS_BFS/\353\217\204\354\240\204/14502.cpp" +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include -using namespace std; - -// 벽을 세우기 위한 모든 경우의 수를 탐색. 빈칸 중 3개의 칸을 선택하여 벽을 세우는 조합을 구해야 한다. -// DFS, BFS 함께 사용하는 백트래킹 문제. - -const int MAX = 8; -int n, m; -int lab[MAX][MAX]; // 연구소 지도 -int temp_lab[MAX][MAX]; // 벽을 세운 후의 임시 지도 -int dx[] = {0, 0, 1, -1}; // 방향 벡터 (상, 하, 좌, 우) -int dy[] = {1, -1, 0, 0}; -int max_safe_area = 0; // 최대 안전 영역 크기 - -// 바이러스를 퍼뜨리기 (BFS 사용) -void spread_virus() { - int spread_lab[MAX][MAX]; - queue> q; - - // temp_lab을 복사해서 spread_lab에 저장 - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - spread_lab[i][j] = temp_lab[i][j]; - if (spread_lab[i][j] == 2) { - q.push({i, j}); // 바이러스가 있는 위치 저장 - } - } - } - - // BFS로 바이러스를 퍼뜨리기 - while (!q.empty()) { - int x = q.front().first; - int y = q.front().second; - q.pop(); - - for (int i = 0; i < 4; i++) { - int nx = x + dx[i]; - int ny = y + dy[i]; - - // 지도 범위 안에 있는 경우 && 빈 칸인 경우 -> 바이러스를 퍼뜨림 - if (nx >= 0 && ny >= 0 && nx < n && ny < m && spread_lab[nx][ny] == 0) { - spread_lab[nx][ny] = 2; - q.push({nx, ny}); - } - } - } - - // 크기 계산 - int safe_area = 0; - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - if (spread_lab[i][j] == 0) { - safe_area++; - } - } - } - - // 갱신 - max_safe_area = max(max_safe_area, safe_area); -} - -// 벽 세우기 (백트래킹) -void build_wall(int count) { - // 벽 3개를 다 세운 경우, 바이러스를 퍼뜨림 - if (count == 3) { - spread_virus(); - return; - } - - // 빈 칸에 벽 세우기 - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - if (temp_lab[i][j] == 0) { - temp_lab[i][j] = 1; // 벽을 세움 - build_wall(count + 1); // 다음 벽 세우기 - temp_lab[i][j] = 0; // 원상 복구 - } - } - } -} - -int main() { - ios::sync_with_stdio(false); - cin.tie(0); - - cin >> n >> m; - - // 연구소 입력 - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - cin >> lab[i][j]; - } - } - - // 연구소 상태를 복사해둔다. - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - temp_lab[i][j] = lab[i][j]; - } - } - - // 벽 세우기 시작 - build_wall(0); - - // 최대 안전 영역 출력 - cout << max_safe_area << '\n'; - - return 0; -} diff --git "a/08_DFS_BFS/\355\225\204\354\210\230/2606.cpp" "b/08_DFS_BFS/\355\225\204\354\210\230/2606.cpp" deleted file mode 100644 index 8549887..0000000 --- "a/08_DFS_BFS/\355\225\204\354\210\230/2606.cpp" +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -using namespace std; - -const int MAX = 100; // 최대 컴퓨터 개수 -vector network[MAX + 1]; // 네트워크 연결 정보 -bool visited[MAX + 1]; // 방문 여부 확인 배열 -int infected_count = 0; // 감염된 컴퓨터 수 - -// DFS로 바이러스 전파 탐색 -void dfs(int computer) { - visited[computer] = true; - infected_count++; // 감염된 컴퓨터 수 증가 - - // 현재 컴퓨터와 연결된 다른 컴퓨터 탐색 - for (int next : network[computer]) { - if (!visited[next]) { // 아직 방문하지 않은 컴퓨터라면 - dfs(next); // 해당 컴퓨터로 이동 - } - } -} - -int main() { - ios::sync_with_stdio(false); // 입출력 속도 향상 - cin.tie(nullptr); - - int n; // 컴퓨터 수 - cin >> n; - - int m; // 네트워크 상에서 연결된 컴퓨터 쌍 개수 - cin >> m; - - // 네트워크 연결 정보 입력 - for (int i = 0; i < m; ++i) { - int u, v; - cin >> u >> v; - network[u].push_back(v); - network[v].push_back(u); // 양방향 연결 - } - - // DFS로 1번 컴퓨터에서 바이러스 전파 시작 - dfs(1); - - // 1번 컴퓨터는 제외하고 출력해야 하므로 -1을 해 줘야 한다. - cout << infected_count - 1 << '\n'; - - return 0; -} diff --git "a/08_DFS_BFS/\355\225\204\354\210\230/2615.cpp" "b/08_DFS_BFS/\355\225\204\354\210\230/2615.cpp" deleted file mode 100644 index 51d1099..0000000 --- "a/08_DFS_BFS/\355\225\204\354\210\230/2615.cpp" +++ /dev/null @@ -1,79 +0,0 @@ -#include -using namespace std; - -const int board_size = 19; // 바둑판 크기 -int board[board_size][board_size]; - -// 방향: 오른쪽, 아래, 대각선 오른쪽 아래, 대각선 왼쪽 아래 -int dx[4] = {0, 1, 1, -1}; -int dy[4] = {1, 0, 1, 1}; - -// 좌표가 유효한지 확인 -bool is_valid(int x, int y) { - return x >= 0 && x < board_size && y >= 0 && y < board_size; -} - -// 승리 여부를 확인 -bool check_win(int x, int y, int color) { - // 4방향 확인 - for (int dir = 0; dir < 4; ++dir) { - int count = 1; // 현재 바둑알 포함 - int nx = x + dx[dir], ny = y + dy[dir]; - - // 동일한 색의 바둑알이 연속으로 있는지 확인 - while (is_valid(nx, ny) && board[nx][ny] == color) { - count++; - nx += dx[dir]; - ny += dy[dir]; - } - - // 반대 방향 확인 - nx = x - dx[dir], ny = y - dy[dir]; - while (is_valid(nx, ny) && board[nx][ny] == color) { - count++; - nx -= dx[dir]; - ny -= dy[dir]; - } - - // 5개의 바둑알이 연속된 경우 - if (count == 5) { - // 이전 좌표가 유효하지 않거나 다른 색인 경우만 승리 인정 - int prev_x = x - dx[dir], prev_y = y - dy[dir]; - if (!is_valid(prev_x, prev_y) || board[prev_x][prev_y] != color) { - cout << color << '\n'; - cout << x + 1 << ' ' << y + 1 << '\n'; // 1-based index로 출력 - return true; - } - } - } - return false; -} - -int main() { - // 입출력 속도 향상 - ios::sync_with_stdio(false); - cin.tie(nullptr); - - // 바둑판 입력 - for (int i = 0; i < board_size; ++i) { - for (int j = 0; j < board_size; ++j) { - cin >> board[i][j]; - } - } - - // 바둑판에서 승리 여부 확인 - for (int i = 0; i < board_size; ++i) { - for (int j = 0; j < board_size; ++j) { - if (board[i][j] != 0) { - // 현재 위치에서 승리 확인 - if (check_win(i, j, board[i][j])) { - return 0; - } - } - } - } - - // 승부가 나지 않았을 경우 - cout << 0 << '\n'; - return 0; -} diff --git "a/08_DFS_BFS/\355\225\204\354\210\230/2644.cpp" "b/08_DFS_BFS/\355\225\204\354\210\230/2644.cpp" deleted file mode 100644 index 7f27ce1..0000000 --- "a/08_DFS_BFS/\355\225\204\354\210\230/2644.cpp" +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -using namespace std; - -const int MAX = 100; // 최대 사람 수 -vector relations[MAX + 1]; // 관계를 저장 -> 인접 리스트 -int visited[MAX + 1]; // 방문 여부, 촌수를 저장하는 배열 - -// BFS로 두 사람 간의 촌수를 계산 -int calculate_relation(int start, int target) { - queue q; - q.push(start); - visited[start] = 0; // 시작점: 자기 자신, 0촌 - - while (!q.empty()) { - int current = q.front(); - q.pop(); - - // 목표 사람에 도달하면 그때의 촌수 반환 - if (current == target) { - return visited[current]; - } - - // 현재 사람과 연결된 사람들을 모두 확인 - for (int next : relations[current]) { - if (visited[next] == -1) { // 아직 방문하지 않은 경우만 - visited[next] = visited[current] + 1; // 촌수 증가 - q.push(next); - } - } - } - - // 목표 사람에 도달하지 못하면 -1 반환 - return -1; -} - -int main() { - ios::sync_with_stdio(false); // 입출력 최적화 - cin.tie(nullptr); - - int n; // 전체 사람 수 - cin >> n; - - int person1, person2; - cin >> person1 >> person2; // 촌수 계산 대상 - - int m; // 부모 자식 관계 수 - cin >> m; - - // 부모-자식 관계 입력 - for (int i = 0; i < m; ++i) { - int parent, child; - cin >> parent >> child; - relations[parent].push_back(child); - relations[child].push_back(parent); // 양방향으로 관계 저장 - } - - // 방문 배열을 -1로 초기화 - for (int i = 1; i <= n; ++i) { - visited[i] = -1; - } - - // 두 사람 간의 촌수를 계산 - int result = calculate_relation(person1, person2); - - cout << result << '\n'; - - return 0; -} diff --git "a/12_\355\212\270\353\246\254/\355\225\204\354\210\230/15681.cpp" "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/15681.cpp" new file mode 100644 index 0000000..a1f7c25 --- /dev/null +++ "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/15681.cpp" @@ -0,0 +1,51 @@ +#include +#include +using namespace std; + +const int MAX_N = 100000; // 최대 정점 수 + +vector tree[MAX_N + 1]; // 트리의 연결 관계를 저장하는 인접 리스트 +int subtree_size[MAX_N + 1]; // 각 정점을 루트로 하는 서브트리의 정점 수 +bool visited[MAX_N + 1]; // 방문 여부를 기록하는 배열 + +// 서브트리 크기를 계산하는 함수 +int calculateSubtreeSize(int node) { + visited[node] = true; // 현재 정점을 방문 표시 + subtree_size[node] = 1; // 자신도 자신의 서브트리에 포함되므로 1로 시작 + + for (int neighbor : tree[node]) { + if (!visited[neighbor]) { // 아직 방문하지 않은 자식 노드 + subtree_size[node] += calculateSubtreeSize(neighbor); // 자식 서브트리 크기를 더함 + } + } + + return subtree_size[node]; // 최종 서브트리 크기를 반환 +} + +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + + int n, r, q; // 정점 수, 루트 번호, 쿼리 수 + cin >> n >> r >> q; + + // 트리 입력 + for (int i = 0; i < n - 1; ++i) { + int u, v; + cin >> u >> v; + tree[u].push_back(v); + tree[v].push_back(u); // 무향 그래프이므로 양방향 간선 + } + + // 서브트리 크기 계산 + calculateSubtreeSize(r); + + // 쿼리 처리 + while (q--) { + int u; + cin >> u; + cout << subtree_size[u] << "\n"; // 각 쿼리 결과 출력 + } + + return 0; +} diff --git "a/12_\355\212\270\353\246\254/\355\225\204\354\210\230/3190.cpp" "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/3190.cpp" new file mode 100644 index 0000000..ec8bfae --- /dev/null +++ "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/3190.cpp" @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +using namespace std; + +// 방향 이동 정의 (우, 하, 좌, 상) +const int dx[] = {0, 1, 0, -1}; +const int dy[] = {1, 0, -1, 0}; + +// 게임에 필요한 상수 정의 +const int EMPTY = 0; // 빈 칸 +const int APPLE = 1; // 사과가 있는 칸 + +// 방향 전환 정보를 저장하기 위한 구조체 +struct DirectionChange { + int time; // 시간 (몇 초 뒤에 방향을 전환할지) + char direction; // 방향 ('L': 왼쪽, 'D': 오른쪽) +}; + +// 게임 진행 함수 +int playGame(int board_size, vector> &board, queue &direction_changes) { + deque> snake; // 뱀의 위치를 저장하는 덱 (머리와 꼬리 관리) + snake.push_back({0, 0}); // 뱀의 초기 위치 (맨 위 맨 좌측) + board[0][0] = -1; // 뱀이 위치한 칸은 -1로 표시 + + int time = 0; // 현재 게임 시간 + int direction = 0; // 초기 방향 (오른쪽) + + while (true) { + time++; // 매 초 증가 + + // 뱀의 머리 위치 계산 + int head_x = snake.front().first; + int head_y = snake.front().second; + int new_x = head_x + dx[direction]; + int new_y = head_y + dy[direction]; + + // 벽이나 자기 몸과 충돌하면 게임 종료 + if (new_x < 0 || new_y < 0 || new_x >= board_size || new_y >= board_size || board[new_x][new_y] == -1) { + break; + } + + // 사과가 있는 칸으로 이동한 경우 + if (board[new_x][new_y] == APPLE) { + board[new_x][new_y] = -1; // 사과를 먹었으므로 해당 칸은 뱀으로 표시 + snake.push_front({new_x, new_y}); // 머리를 새 위치로 이동 + } else { // 빈 칸으로 이동한 경우 + board[new_x][new_y] = -1; // 새 위치를 뱀으로 표시 + snake.push_front({new_x, new_y}); // 머리를 새 위치로 이동 + + // 꼬리를 줄여야 하므로 꼬리가 있던 칸을 비운다 + auto tail = snake.back(); + snake.pop_back(); + board[tail.first][tail.second] = EMPTY; + } + + // 방향 전환 처리 + if (!direction_changes.empty() && direction_changes.front().time == time) { + char turn = direction_changes.front().direction; + direction_changes.pop(); + if (turn == 'L') { + direction = (direction + 3) % 4; // 왼쪽으로 90도 회전 + } else if (turn == 'D') { + direction = (direction + 1) % 4; // 오른쪽으로 90도 회전 + } + } + } + + return time; +} + +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + + int board_size, apple_count; + cin >> board_size >> apple_count; + + // 보드 초기화 + vector> board(board_size, vector(board_size, EMPTY)); + + // 사과 위치 입력 + for (int i = 0; i < apple_count; i++) { + int x, y; + cin >> x >> y; + board[x - 1][y - 1] = APPLE; // 입력은 1-based, 내부 보드는 0-based + } + + // 방향 전환 정보 입력 + int direction_change_count; + cin >> direction_change_count; + queue direction_changes; + for (int i = 0; i < direction_change_count; i++) { + int time; + char direction; + cin >> time >> direction; + direction_changes.push({time, direction}); + } + + // 게임 실행 및 결과 출력 + cout << playGame(board_size, board, direction_changes) << "\n"; + + return 0; +} diff --git "a/12_\355\212\270\353\246\254/\355\225\204\354\210\230/5639.cpp" "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/5639.cpp" new file mode 100644 index 0000000..3577b69 --- /dev/null +++ "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/5639.cpp" @@ -0,0 +1,61 @@ +#include +#include +#include +using namespace std; + +struct TreeNode { + int value; + TreeNode *left; + TreeNode *right; + TreeNode(int v) : value(v), left(nullptr), right(nullptr) {} +}; + +// 트리를 구성하는 함수 +TreeNode* buildTree(vector& preorder, int& index, int min_value, int max_value) { + if (index >= preorder.size()) { + return nullptr; + } + + int current_value = preorder[index]; + if (current_value < min_value || current_value > max_value) { + return nullptr; + } + + // 현재 값을 사용하여 노드 생성 + TreeNode* node = new TreeNode(current_value); + index++; // 다음 값을 처리 + + // 왼쪽과 오른쪽 서브트리 재귀적으로 구성 + node->left = buildTree(preorder, index, min_value, current_value); + node->right = buildTree(preorder, index, current_value, max_value); + + return node; +} + +// 후위 순회를 수행하여 결과 출력 +void postorderTraversal(TreeNode* node) { + if (node == nullptr) { + return; + } + postorderTraversal(node->left); + postorderTraversal(node->right); + cout << node->value << "\n"; +} + +int main() { + ios::sync_with_stdio(false); + cin.tie(nullptr); + + vector preorder; + int value; + while (cin >> value) { + preorder.push_back(value); + } + + int index = 0; + TreeNode* root = buildTree(preorder, index, INT_MIN, INT_MAX); + + postorderTraversal(root); + + return 0; +}