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/13_\354\265\234\353\213\250\352\262\275\353\241\234/\355\225\204\354\210\230/1238.cpp" "b/13_\354\265\234\353\213\250\352\262\275\353\241\234/\355\225\204\354\210\230/1238.cpp" new file mode 100644 index 0000000..575911f --- /dev/null +++ "b/13_\354\265\234\353\213\250\352\262\275\353\241\234/\355\225\204\354\210\230/1238.cpp" @@ -0,0 +1,84 @@ +#include +#include +#include +#include +using namespace std; + +// 무한대를 나타내기 위한 상수 +const int INF = numeric_limits::max(); + +// 그래프의 간선을 표현하는 구조체 +struct Edge { + int target; // 연결된 노드 + int weight; // 해당 간선의 가중치 +}; + +// 다익스트라 알고리즘 함수 +// 주어진 시작점(start)에서 다른 모든 노드까지의 최단 거리를 계산 +vector dijkstra(int start, const vector>& graph) { + int n = graph.size(); // 그래프의 크기 (노드 수) + vector distance(n, INF); // 시작점으로부터의 최단 거리를 저장 (초기값은 무한대) + priority_queue, vector>, greater<>> min_heap; + + distance[start] = 0; // 시작점까지의 거리는 0 + min_heap.push({0, start}); // 우선순위 큐에 {거리, 노드} 형태로 추가 + + while (!min_heap.empty()) { + int current_dist = min_heap.top().first; // 현재 노드까지의 거리 + int current_node = min_heap.top().second; // 현재 노드 + min_heap.pop(); + + // 큐에서 꺼낸 거리 정보가 이미 최적 거리보다 크다면 무시 + if (current_dist > distance[current_node]) { + continue; + } + + // 현재 노드와 연결된 모든 인접 노드 탐색 + for (const auto& edge : graph[current_node]) { + int next_node = edge.target; // 다음 노드 + int new_dist = current_dist + edge.weight; // 새로운 거리 계산 + + // 더 짧은 경로를 발견하면 최단 거리 갱신 + if (new_dist < distance[next_node]) { + distance[next_node] = new_dist; // 최단 거리 업데이트 + min_heap.push({new_dist, next_node}); // 큐에 새로운 거리와 노드 추가 + } + } + } + + return distance; // 시작점에서 각 노드까지의 최단 거리 배열 반환 +} + +int main() { + int n, m, x; + cin >> n >> m >> x; // n: 마을의 수, m: 도로의 수, x: 파티가 열리는 마을 번호 + + // 그래프와 역방향 그래프를 저장할 2차원 벡터 + vector> graph(n + 1); // 정방향 그래프 (1번 마을부터 시작) + vector> reverse_graph(n + 1); // 역방향 그래프 (X로 돌아오는 경로 계산용) + + // 도로 정보 입력 + for (int i = 0; i < m; i++) { + int u, v, t; + cin >> u >> v >> t; // u에서 v로 가는 도로의 소요 시간 t + graph[u].push_back({v, t}); // 정방향 그래프에 추가 + reverse_graph[v].push_back({u, t}); // 역방향 그래프에 추가 + } + + // X로 가는 최단 거리 계산 (모든 마을 -> X) + vector to_x = dijkstra(x, reverse_graph); + + // X에서 오는 최단 거리 계산 (X -> 모든 마을) + vector from_x = dijkstra(x, graph); + + // 왕복 시간이 가장 오래 걸리는 학생의 왕복 시간 계산 + int max_time = 0; // 왕복 시간의 최대값을 저장할 변수 + for (int i = 1; i <= n; i++) { + max_time = max(max_time, to_x[i] + from_x[i]); // 각 학생의 왕복 시간 계산 + } + + // 결과 출력 + cout << max_time << "\n"; // 왕복 시간이 가장 오래 걸리는 학생의 시간 출력 + + return 0; +} diff --git "a/13_\354\265\234\353\213\250\352\262\275\353\241\234/\355\225\204\354\210\230/15685.cpp" "b/13_\354\265\234\353\213\250\352\262\275\353\241\234/\355\225\204\354\210\230/15685.cpp" new file mode 100644 index 0000000..54ccba1 --- /dev/null +++ "b/13_\354\265\234\353\213\250\352\262\275\353\241\234/\355\225\204\354\210\230/15685.cpp" @@ -0,0 +1,67 @@ +#include +#include +#include +using namespace std; + +// 방향 배열: 0 →, 1 ↑, 2 ←, 3 ↓ +const int DX[4] = {1, 0, -1, 0}; +const int DY[4] = {0, -1, 0, 1}; +const int MAX_GRID = 101; + +int grid[MAX_GRID][MAX_GRID]; // 격자 상태를 저장 + +// 드래곤 커브 생성 함수 +void generateDragonCurve(int x, int y, int d, int g) { + vector directions; // 드래곤 커브의 방향 저장 + directions.push_back(d); // 0세대 방향 추가 + + // g세대 방향 계산 + for (int gen = 1; gen <= g; gen++) { + int size = directions.size(); + for (int i = size - 1; i >= 0; i--) { + directions.push_back((directions[i] + 1) % 4); // 90도 회전 + } + } + + // 드래곤 커브 격자에 기록 + grid[y][x] = 1; // 시작 점 표시 + for (int dir : directions) { + x += DX[dir]; + y += DY[dir]; + grid[y][x] = 1; // 이동한 점 표시 + } +} + +// 1x1 정사각형 개수 계산 함수 +int countSquares() { + int count = 0; + for (int y = 0; y < MAX_GRID - 1; y++) { + for (int x = 0; x < MAX_GRID - 1; x++) { + // 1x1 정사각형의 네 꼭짓점이 모두 드래곤 커브의 일부인지 확인 + if (grid[y][x] && grid[y + 1][x] && grid[y][x + 1] && grid[y + 1][x + 1]) { + count++; + } + } + } + return count; +} + +int main() { + int n; // 드래곤 커브의 개수 + cin >> n; + + // 입력 받고 드래곤 커브 생성 + for (int i = 0; i < n; i++) { + int x, y, d, g; + cin >> x >> y >> d >> g; + generateDragonCurve(x, y, d, g); + } + + // 1x1 정사각형 개수 계산 + int result = countSquares(); + + // 결과 출력 + cout << result << "\n"; + + return 0; +} diff --git "a/13_\354\265\234\353\213\250\352\262\275\353\241\234/\355\225\204\354\210\230/2458.cpp" "b/13_\354\265\234\353\213\250\352\262\275\353\241\234/\355\225\204\354\210\230/2458.cpp" new file mode 100644 index 0000000..b25e285 --- /dev/null +++ "b/13_\354\265\234\353\213\250\352\262\275\353\241\234/\355\225\204\354\210\230/2458.cpp" @@ -0,0 +1,76 @@ +#include +#include + +using namespace std; + +const int MAX_N = 500 + 1; // 최대 학생 수 (인덱스를 1부터 사용하기 위해 +1) + +// 학생들 간의 키 비교 결과를 저장하는 행렬 +bool adjacency_matrix[MAX_N][MAX_N]; + +void floydWarshall(int n) { + // 플로이드-워셜 알고리즘을 사용하여 모든 학생 쌍의 키 비교 결과를 계산 + for (int k = 1; k <= n; k++) { + for (int i = 1; i <= n; i++) { + if (adjacency_matrix[i][k]) { + for (int j = 1; j <= n; j++) { + if (adjacency_matrix[k][j]) { + adjacency_matrix[i][j] = true; + } + } + } + } + } +} + +int countKnownRanks(int n) { + int count = 0; // 자신의 순위를 알 수 있는 학생의 수 + + for (int i = 1; i <= n; i++) { + int known_relations = 0; // i번 학생과 직접 또는 간접적으로 비교된 학생의 수 + + for (int j = 1; j <= n; j++) { + if (i == j) continue; // 자기 자신은 비교하지 않음 + + // i번 학생이 j번 학생보다 작거나 큰 경우 + if (adjacency_matrix[i][j] || adjacency_matrix[j][i]) { + known_relations++; + } + } + + // 자신을 제외한 모든 학생들과의 키 비교 결과를 알면 순위를 알 수 있음 + if (known_relations == n - 1) { + count++; + } + } + + return count; +} + +int main() { + int n, m; // n: 학생 수, m: 키 비교한 학생 쌍의 수 + cin >> n >> m; + + // adjacency_matrix 초기화 + for (int i = 1; i <= n; i++) { + fill(adjacency_matrix[i], adjacency_matrix[i] + n + 1, false); + } + + // 키 비교 결과 입력 + for (int i = 0; i < m; i++) { + int a, b; + cin >> a >> b; + adjacency_matrix[a][b] = true; // a번 학생이 b번 학생보다 키가 작음 + } + + // 모든 학생 쌍에 대해 키 비교 결과 계산 + floydWarshall(n); + + // 순위를 알 수 있는 학생의 수 계산 + int result = countKnownRanks(n); + + // 결과 출력 + cout << result << endl; + + return 0; +}