diff --git a/.vscode/settings.json b/.vscode/settings.json index 4d1c62b7..7c6f3d1e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,48 @@ "algorithm": "cpp", "xiosbase": "cpp", "xlocale": "cpp", - "xutility": "cpp" + "xutility": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "deque": "cpp", + "exception": "cpp", + "initializer_list": "cpp", + "ios": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "map": "cpp", + "memory": "cpp", + "new": "cpp", + "ostream": "cpp", + "queue": "cpp", + "set": "cpp", + "stack": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "xfacet": "cpp", + "xlocinfo": "cpp", + "xlocnum": "cpp", + "xmemory": "cpp", + "xstddef": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xtree": "cpp" } } diff --git "a/12_\355\212\270\353\246\254/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_1991.cpp" "b/12_\355\212\270\353\246\254/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_1991.cpp" new file mode 100644 index 00000000..43c1739f --- /dev/null +++ "b/12_\355\212\270\353\246\254/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_1991.cpp" @@ -0,0 +1,66 @@ +#include +#include + +using namespace std; + +map> tree; + +// 전위 순회는 V - L - R +void preorder(char v) +{ + if (v == '.') + { + return; + } + cout << v; + preorder(tree[v].first); + preorder(tree[v].second); +} + +// 중위 순회 L - V - R +void inorder(char v) +{ + if (v == '.') + { + return; + } + + inorder(tree[v].first); + cout << v; + inorder(tree[v].second); +} + +// 후위 순회 L - R - V +void postorder(char v) +{ + if (v == '.') + { + return; + } + + postorder(tree[v].first); + postorder(tree[v].second); + cout << v; +} + +int main() +{ + int n; + char root, left, right; + + // 입력 + cin >> n; + while (n--) + { + cin >> root >> left >> right; + tree[root] = {left, right}; + } + + // 연산 + 출력 + preorder('A'); + cout << '\n'; + inorder('A'); + cout << '\n'; + postorder('A'); + return 0; +} \ No newline at end of file diff --git "a/12_\355\212\270\353\246\254/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_4803.cpp" "b/12_\355\212\270\353\246\254/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_4803.cpp" new file mode 100644 index 00000000..e25528d5 --- /dev/null +++ "b/12_\355\212\270\353\246\254/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_4803.cpp" @@ -0,0 +1,99 @@ +#include +#include + +using namespace std; + +// 결과 출력 함수 +void printResult(int tc, int cnt) +{ + cout << "Case " << tc << ": "; + + switch (cnt) + { + case 0: + cout << "No trees.\n"; + break; + case 1: + cout << "There is one tree.\n"; + break; + default: + cout << "A forest of " << cnt << " trees.\n"; + } + return; +} + +void dfs(bool &flag, int cur, int prev, vector> &graph, vector &visited) +{ + + if (visited[cur]) + { // 방문했던 곳을 또 방문했다면 트리가 아니다 + flag = false; + return; + } + + visited[cur] = true; // 방문 체크 + + for (int next : graph[cur]) + { + if (next == prev) + { + continue; + } + dfs(flag, next, cur, graph, visited); + } + return; +} + +/* + * 각 그래프가 트리인지 아닌지 판단 + * 사이클이 생기면 트리 아님 + * 사이클이 생긴다 -> DFS로 자기 자신으로 돌아올 수 있다. + */ + +int main() +{ + int n, m, t, v1, v2; + + for (t = 1;; t++) + { // 테스트 케이스 번호 + + // 입력 + cin >> n >> m; + + if (!n && !m) + { // 종료 조건 + break; + } + + // 그래프 입력 + vector> graph(n + 1, vector(0)); + for (int i = 0; i < m; i++) + { + cin >> v1 >> v2; + graph[v1].push_back(v2); + graph[v2].push_back(v1); + } + + int cnt = 0; // 트리 수 카운트 + vector visited(n + 1, false); // 방문 표시 + + for (int i = 1; i <= n; i++) + { + if (visited[i]) + { + continue; + } + + bool flag = true; // 트리인지 여부 저장하는 변수 + dfs(flag, i, 0, graph, visited); + if (flag) + { + cnt++; + } + } + + // 출력 + printResult(t, cnt); + } + return 0; +} \ No newline at end of file diff --git "a/12_\355\212\270\353\246\254/\355\225\204\354\210\230/BOJ_15681.cpp" "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/BOJ_15681.cpp" new file mode 100644 index 00000000..8e881a0c --- /dev/null +++ "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/BOJ_15681.cpp" @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +using namespace std; + +#define MAX 100000 + 1 // MAX상수 선언 + +int n, r, q; // 정점 수, 루트 번호, 쿼리 수 +int from, to; // 간선 입력 +int q_num; // 쿼리 번호 +vector connect[MAX]; +int dp[MAX]; +bool visited[MAX]; + +void Input() +{ + cin >> n >> r >> q; + for (int i = 0; i < n - 1; i++) + { + cin >> from >> to; + connect[from].push_back(to); + connect[to].push_back(from); + } +} + +int countSubTree(int now) +{ + if (visited[now]) + { + return dp[now]; + } + visited[now] = true; + int subTreeNum = 1; + for (int i = 0; i < connect[now].size(); i++) + { + int childNum = connect[now][i]; + if (visited[childNum]) + { + continue; + } + else + { + subTreeNum += countSubTree(childNum); + } + } + dp[now] = subTreeNum; + return dp[now]; +} + +int main() +{ + ios_base ::sync_with_stdio(false); // 시간 단축 + cin.tie(NULL); + cout.tie(NULL); + + Input(); + + memset(visited, 0, sizeof(visited)); + memset(dp, 0, sizeof(dp)); + dp[r] = countSubTree(r); // 루트 노드로부터 자식 노드 구하기 + + for (int j = 0; j < q; j++) + { + cin >> q_num; + cout << dp[q_num] << '\n'; + } + + return 0; +} diff --git "a/12_\355\212\270\353\246\254/\355\225\204\354\210\230/BOJ_3190.cpp" "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/BOJ_3190.cpp" new file mode 100644 index 00000000..20aa1dab --- /dev/null +++ "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/BOJ_3190.cpp" @@ -0,0 +1,100 @@ +#include +#include +#include +#include + +using namespace std; +typedef pair ci; // 쌍의 구조체 ci선언 + +/**뱀 게임이 종료되는 시간 계산*/ +int game(int n, vector> &state, map &direction) +{ + int dx[4] = {0, 1, 0, -1}; // 동(→), 남(↓), 서(←), 북(↑) + int dy[4] = {1, 0, -1, 0}; + int time = 0; // 게임 시간 + int dir = 0; // 뱀의 방향 + int x, y, nx, ny; // 뱀의 머리 좌표를 나타낼 변수들 + + deque snake; // 뱀의 위치 + snake.push_back({1, 1}); // 뱀의 시작 좌표 추가 + state[1][1] = 2; // (1, 1)에 뱀이 있음을 표시 + + while (true) + { + x = snake.front().first; // 뱀의 머리 좌표 + y = snake.front().second; + if (direction[time] != 0) + { // 뱀의 방향 변환 정보가 있으면 + dir = (dir + direction[time]) % 4; // 뱀의 방향 갱신 + } + time++; // 게임 시간 1초 추가 + nx = x + dx[dir]; // 뱀 머리의 다음 좌표 + ny = y + dy[dir]; + + // 뱀의 머리가 벽에 부딪히거나 자기 자신의 몸과 부딪히면 게임 종료 + if (!(0 < nx && nx <= n) || !(0 < ny && ny <= n) || state[nx][ny] == 2) + { + break; // 게임종료 + } + + snake.push_front({nx, ny}); // 뱀의 머리 좌표 추가 + if (state[nx][ny] != 1) + { // 새로 이동한 좌표에 사과가 없으면 꼬리 위치 비워주기 + state[snake.back().first][snake.back().second] = 0; // 꼬리위치설정 + snake.pop_back(); // 뱀의 위치 제거 + } + state[nx][ny] = 2; // 뱀이 존재 + } + return time; // 게임시간 반환 +} +/**[백준 3190: 뱀] + * 뱀의 머리와 꼬리 좌표에 대한 접근 필요 -> deque 사용! + * state에 사과가 존재하면 해당 위치를 1, 뱀이 존재하면 2, 아무것도 없으면 0으로 설정 + * 1. 뱀의 첫 시작 좌표인 {1, 1}을 s에 추가 + * 2. 현재 뱀의 머리가 있는 좌표를 {x, y}로 받기 + * 3. 뱀의 방향이 바뀌면 방향을 업데이트하고, 새로운 뱀의 머리 좌표를 {nx, ny}로 설정 + * 4. 게임 시간 업데이트(time++) + * 4. 뱀의 머리가 벽이나 몸에 부딪히면 while문 종료 + * 5-1. 새로 이동한 좌표를 s 앞부분에 추가 + * 5-2. 새로 이동한 좌표에 사과가 없으면 기존 꼬리 좌표 값을 0으로 바꾸고 s에서 pop + * -> 사과가 있으면 몸길이가 1 늘어나지만 사과가 없으면 몸길이가 변하지 않으므로 + * 6. 새로 이동한 좌표를 2로 표시 + */ +int main() +{ + int n, k, l, x; // 보드의 크기n, 사과의 개수 k, 뱀의 변환횟수 l, 게임시간 x초 + char c; // + vector> state; // 사과의 위치를 나타낼 이중벡터state + map direction; // 방향을 가리키는 map + + // 입력 + cin >> n >> k; // 보드의 크기, 사과의 개수 사용자정의 + state.assign(n + 1, vector(n + 1, 0)); // int로 구성된 n+1개의 vector를 0으로 초기화 + while (k--) // k번 반복 + { + int a, b; // 사과위치의 x좌표, y 좌표 + cin >> a >> b; // 사용자정의 + state[a][b] = 1; // 사과 위치 표시 + } + + cin >> l; // 방향변환 번수 사용자정의 + while (l--) // l번 반복 + { + cin >> x >> c; + if (c == 'D') //'D'이면 + { + direction[x] = 1; // 오른쪽으로 회전 + } + else // 'L'이면 + { + direction[x] = 3; // 왼쪽으로 회전 + } + } + + // 연산 + int time = game(n, state, direction); // 게임시간 반환 + + // 출력 + cout << time; + return 0; +} \ No newline at end of file diff --git "a/12_\355\212\270\353\246\254/\355\225\204\354\210\230/BOJ_5639.cpp" "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/BOJ_5639.cpp" new file mode 100644 index 00000000..b734028f --- /dev/null +++ "b/12_\355\212\270\353\246\254/\355\225\204\354\210\230/BOJ_5639.cpp" @@ -0,0 +1,42 @@ +#include +#include + +using namespace std; + +vector arr; + +void postOrder(int start, int end, vector &v) +{ + if (start >= end) // start >= end이면 break + { + return; + } + int idx = start + 1; // start보다 커지면 좌측 자식노드로 + + while (idx < end) + { + if (v[start] < v[idx]) + { // v[start] < v[idx] 될 때까지 idx값을 늘려준다. + break; + } + idx++; + } + postOrder(start + 1, idx, v); // 좌측 자식노드에 대해 재귀적으로 함수 호출 + postOrder(idx, end, v); // 우측 자식노드에 대해 재귀적으로 함수 호출 + cout << v[start] << "\n"; +} + +int main() +{ + int n; + ios::sync_with_stdio(false); // 시간단축 + cin.tie(NULL); + cout.tie(NULL); + while (cin >> n) + { + arr.push_back(n); // n을 사용자입력 받아서 arr배열에 push + } + postOrder(0, arr.size(), arr); + + return 0; +} diff --git "a/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_11404.cpp" "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_11404.cpp" new file mode 100644 index 00000000..380e3d3d --- /dev/null +++ "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_11404.cpp" @@ -0,0 +1,33 @@ +#include +#include +#include + +const int INF = 1e7; // 정적의 개수 V * (가중치의 최대값) +using namespace std; + +void foydWarshall(int n, vector> &graph) +{ + for (int k = 1; k <= n; k++) + { + for (int i = 1; i <= n; i++) + { + } + } +} + +int main() +{ + + int n, m, a, b, c; // 도시의 개수 n, 버스의 개수m ,이동 비용c + cin >> n >> m; + vector> graph(n + 1, vector(n + 1, INF)); + + for (int i = 1; i <= n; i++) + { + graph[i][i] = 0; + } + while (m--) + { + cin >> a >> b >> c; + } +} \ No newline at end of file diff --git "a/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_11657.cpp" "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_11657.cpp" new file mode 100644 index 00000000..e69de29b diff --git "a/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_1753.cpp" "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_1753.cpp" new file mode 100644 index 00000000..ad69bae1 --- /dev/null +++ "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\353\235\274\354\235\264\353\270\214 \354\275\224\353\224\251/BOJ_1753.cpp" @@ -0,0 +1,15 @@ +#include +#include +#include + +using namespace std; +typedef pair ci; +const int INF = 2e5; // v * 가중치와 최대값 이유는 나중에 + +int main() +{ + int v, e, k, a, b, w; + + cin >> v >> e >> k; // 정점의 개수v, 간선의 개수e, 간선의 가중치 w + vector> graph(v + 1, vector(0)); +} \ No newline at end of file diff --git "a/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\355\225\204\354\210\230/BOJ_1238.cpp" "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\355\225\204\354\210\230/BOJ_1238.cpp" new file mode 100644 index 00000000..1182a9dd --- /dev/null +++ "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\355\225\204\354\210\230/BOJ_1238.cpp" @@ -0,0 +1,75 @@ +#include +#include +#include + +using namespace std; + +typedef pair ci; +const int INF = 1e6; +vector> graph, rev_graph; // 이중벡터 순방향 그래프, 역방향 그래프 선언 + +vector dijkstra(int start, int n, vector> g) +{ + vector time(n + 1, INF); + priority_queue, greater<>> pq; + + // 시작 지점 초기화 + time[start] = 0; + pq.push({0, start}); + + while (!pq.empty()) + { + int weight = pq.top().first; + int node = pq.top().second; + pq.pop(); + + if (weight > time[node]) + continue; // 이미 방문한 노드는 pass + + for (int i = 0; i < g[node].size(); i++) + { + int new_node = g[node][i].first; + int new_weight = weight + g[node][i].second; + + if (time[new_node] > new_weight) + { // 더 짧은 경로 발견시에 + time[new_node] = new_weight; + pq.push({new_weight, new_node}); + } + } + } + return time; +} + +int main() +{ + int n, m, x; + cin >> n >> m >> x; // n명의 학생 , m개의 단방향 도로, 할당시간 x + + // 단방향과 역방향을 모두 0으로 init + graph.assign(n + 1, vector(0)); + rev_graph.assign(n + 1, vector(0)); + + while (m--) + { // m개의 간선 + int a, b, tm; + cin >> a >> b >> tm; + + // a에서 b로 가는데의 가중치 : tm + graph[a].push_back({b, tm}); + rev_graph[b].push_back({a, tm}); + } + + vector go = dijkstra(x, n, rev_graph); // 모든 정점에서 x로 가는 최단 경로 + vector back = dijkstra(x, n, graph); // x에서 모든 정점까지 가는 최단 경로 + + int ans = 0; + for (int i = 1; i <= n; i++) + { + ans = max(ans, go[i] + back[i]); // 가장 오래걸리는 시간 + } + + // 출력 + cout << ans; + return 0; +} diff --git "a/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\355\225\204\354\210\230/BOJ_15685.cpp" "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\355\225\204\354\210\230/BOJ_15685.cpp" new file mode 100644 index 00000000..e69de29b diff --git "a/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\355\225\204\354\210\230/BOJ_2458.cpp" "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\355\225\204\354\210\230/BOJ_2458.cpp" new file mode 100644 index 00000000..fa461588 --- /dev/null +++ "b/13_\354\265\234\353\213\250 \352\262\275\353\241\234/\355\225\204\354\210\230/BOJ_2458.cpp" @@ -0,0 +1,68 @@ +#include +#define MAX 501 +#define INF 1e9 + +using namespace std; + +int h[MAX][MAX]; // 키 비교완료 시 1, 아니면 INF + +void init() +{ + for (int i = 1; i < MAX; i++) + { + for (int j = 1; j < MAX; j++) + { + h[i][j] = INF; // INF로 초기화 + } + } +} + +void floyd(int n) +{ + for (int k = 1; k <= n; k++) + { // k : 거쳐가는 정점 + for (int i = 1; i <= n; i++) + { // i : 행(출발 정점) + for (int j = 1; j <= n; j++) + { // j : 열(도착 정점) + h[i][j] = min(h[i][j], h[i][k] + h[k][j]); + } + } + } +} + +int main() +{ + ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 시간단축 + + int n, m; // n : 학생의 수, m : 비교한 횟수 + cin >> n >> m; + + init(); + + for (int i = 0; i < m; i++) + { + int a, b; // 학생의 키를 비교한 결과 + cin >> a >> b; // a번 학생이 b번 학생보다 작음 + h[a][b] = 1; // 키 비교 체크 + } + + floyd(n); + int ans = 0; // 자신의 키가 몇 번째인지 알 수 있는 학생 ( = 자기말고 모두와 비교완료된 경우 ) + + for (int i = 1; i <= n; i++) + { + int cnt = 0; + for (int j = 1; j <= n; j++) + { + if (h[i][j] != INF || h[j][i] != INF) + { // i번, j번 학생 키의 대소관계를 아는 경우 + cnt++; + } + } + if (cnt == n - 1) // 자기를 제외한 모든 사람과의 비교가 완료된 경우 + ans++; // ans ++ + } + cout << ans; + return 0; +} \ No newline at end of file