diff --git "a/11_\355\210\254 \355\217\254\354\235\270\355\204\260/\355\225\204\354\210\230/14503.cpp" "b/11_\355\210\254 \355\217\254\354\235\270\355\204\260/\355\225\204\354\210\230/14503.cpp" deleted file mode 100644 index 9e3c6603..00000000 --- "a/11_\355\210\254 \355\217\254\354\235\270\355\204\260/\355\225\204\354\210\230/14503.cpp" +++ /dev/null @@ -1,81 +0,0 @@ -#include - -using namespace std; - -const int SIZE = 50; // 방의 사이즈 -const int CLEAN = 2; // 청소완료 -int n, m, cnt = 0; // 세로 크기, 가로 크기, 청소한 칸 개수 - -int board[SIZE][SIZE]; // (0: 빈 칸, 1: 벽, 2: 청소 완료) -int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0}; // 북 동 남 서 - -void dfs(int row, int col, int dir) { - // 1. 현재 위치 청소 - if(board[row][col] != CLEAN) { - cnt++; - } - // 현재 위치를 청소됨 상태로 바꾸기 - board[row][col] = CLEAN; - - // [현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는가] - // 3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우 - for(int i = 0; i < 4; i++) { // 3-1. 반시계 방향으로 90º 회전 - int new_dir = (dir-i+3) % 4; - // 회전한 후 로봇 청소기 바로 앞의 칸의 row, col - int new_row = row + dy[new_dir], new_col = col + dx[new_dir]; - - if(board[new_row][new_col] == 0) { // 3-2. 아직 청소되지 않은 빈 칸 발견 - dfs(new_row, new_col, new_dir); // 한 칸 전진 - return; - } - } - - // 2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우 - // 뒤로 회전 - int back_dir = (dir+2) % 4; - // 뒤로 회전한 채로 바라보는 방향 - int back_row = row + dy[back_dir], back_col = col + dx[back_dir]; - - // [바라보는 방향을 유지한 채로 한 칸 후진할 수 있는가] - // 2-2. 뒤쪽 칸이 벽이라 후진할 수 없는 경우 - if(board[back_row][back_col] == 1) { - return; - } - // 2-1. 바라보는 방향을 유지한 채로 한 칸 후진 - dfs(back_row, back_col, dir); // 방향 유지한 상태로 후진 (2-3) - return; -} - -/* - * [로봇 청소기 작동] - * 1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다. - * 2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우, - * 2-1. 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다. - * 2-2. 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다. - * 3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우, - * 3-1. 반시계 방향으로 90º 회전한다. - * 3-2. 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다. - * 3-3. 1번으로 돌아간다. -*/ - -int main() { - int r, c, d; // 로봇 청소기 정보 - - // 입력 - cin >> n >> m; - cin >> r >> c >> d; - - // 방의 상태 입력받기 - for(int i = 0; i < n; i++) { - for(int j = 0; j < m; j++) { - cin >> board[i][j]; - } - } - - // 연산 - dfs(r, c, d); - - // 출력 - cout << cnt; - return 0; -} \ No newline at end of file diff --git "a/11_\355\210\254 \355\217\254\354\235\270\355\204\260/\355\225\204\354\210\230/20437.cpp" "b/11_\355\210\254 \355\217\254\354\235\270\355\204\260/\355\225\204\354\210\230/20437.cpp" deleted file mode 100644 index c33341a8..00000000 --- "a/11_\355\210\254 \355\217\254\354\235\270\355\204\260/\355\225\204\354\210\230/20437.cpp" +++ /dev/null @@ -1,70 +0,0 @@ -#include "iostream" -#include "vector" - -using namespace std; - -const int alphabet_num = 26; -const int MAX = 2147483647; - -pair getResult(string w, int k){ - int short_seq = MAX, long_seq = 0; - vector> count(alphabet_num, vector(0)); - - // 문자열 내의 각 문자의 위치를 저장 - for(int i=0; i count[i][end] - count[i][start] + 1 ) ? tmp_long : count[i][end] - count[i][start] + 1; - start++, end++; - } - short_seq = (short_seq < tmp_short) ? short_seq : tmp_short; - long_seq = (long_seq > tmp_long) ? long_seq :tmp_long; - } - // 조건을 만족하지 못하는 경우에는 -1 - if(short_seq == MAX || long_seq == 0){ - return {-1, -1}; - } - return {short_seq, long_seq}; - -} - -int main(){ - ios_base::sync_with_stdio(0); - cin.tie(0); - cout.tie(0); - - int t, k; - string w; - pair result; - - // 입력 - cin >> t; - while(t--){ - cin >> w; - cin >> k; - // 연산 - result = getResult(w, k); - - // 출력 - if(result.first == -1){ - cout << -1; - } - else{ - cout << result.first << " " << result.second; - } - cout << '\n'; - } -} \ No newline at end of file diff --git "a/11_\355\210\254 \355\217\254\354\235\270\355\204\260/\355\225\204\354\210\230/20922.cpp" "b/11_\355\210\254 \355\217\254\354\235\270\355\204\260/\355\225\204\354\210\230/20922.cpp" deleted file mode 100644 index a453fc5f..00000000 --- "a/11_\355\210\254 \355\217\254\354\235\270\355\204\260/\355\225\204\354\210\230/20922.cpp" +++ /dev/null @@ -1,47 +0,0 @@ -#include "iostream" -#include "vector" -#include "map" - -using namespace std; - -int getSequence(int k, vector numbers){ - int start=0, end=0; - int length=0; - map n_count; // 숫자의 개수를 세어줄 map - - // end가 numbers의 끝까지 도달할 때까지 - while(end < numbers.size()){ - // 현재 end가 가리키고 있는 숫자의 개수를 늘려준다 - n_count[numbers[end]]++; - - // 만약 k개보다 end가 가리키고 있는 숫자의 개수가 많다면 - if(n_count[numbers[end]] > k){ - // k보다 작아질때까지 start를 전진시켜줌 - // 이때 start가 앞으로 감에 의해 제외되는 숫자들에 대해서 개수 처리를 해준다. - while (n_count[numbers[end]] > k) { - n_count[numbers[start]]--; - start++; - } - } - // lenght 업데이트 - length = (length > (end - start + 1)) ? length : (end - start +1); - end++; - } - return length; -} - -int main(){ - int n, k; - vector numbers; - - // 입력 - cin >> n >> k; - numbers.assign(n, 0); - - for(int i=0; i> numbers[i]; - } - - // 연산과 출력 - cout << getSequence(k, numbers); -} \ 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/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 00000000..d3347647 --- /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,68 @@ +#include "iostream" +#include "vector" +#include "queue" +#include "algorithm" + +using namespace std; + +const int INF = 1000000; + +typedef pair ci; + +int dijkstra(vector> &nodes, int start, int dest, int n){ + vector dist(n+1, INF); + + priority_queue, greater<>> pq; + + // 시작정점 초기화 + dist[start] = 0; + pq.push({0, start}); + while (!pq.empty()) { + int weight = pq.top().first; // 현재 정점까지의 경로값 + int node = pq.top().second; // 현재 탐색하려는 정점 + pq.pop(); + + if (weight > dist[node]) { // 이미 더 작은 값으로 기록된 정점 + continue; + } + for (int i = 0; i < nodes[node].size(); i++) { + int next_node = nodes[node][i].first; // 연결된 정점 + // 시작점으로부터 현재 node를 거쳐 다음 정점까지 가는 경로값 + int next_weight = weight + nodes[node][i].second; + if (next_weight < dist[next_node]) { // 최단 경로 값이 갱신된다면 + dist[next_node] = next_weight; + pq.push({next_weight, next_node}); + } + } + } + return dist[dest]; +} + +int result(vector> &nodes, int dest, int n){ + int tmp, result = 0; + // 모든 학생의 파티까지의 왕복 거리에 대해서 dijkstra알고리즘 실행 + for(int i=1; i<=n; i++){ + // tmp는 시작점에서 파티장소까지 갈 떄의 거리와 파티장소에서 시작점으로 돌아올 떄의 거리 합 + tmp = dijkstra(nodes, i, dest, n) + dijkstra(nodes, dest, i, n); + // result와 tmp중 값이 더 큰 것으로 result를 갱신 + result = max(result, tmp); + } + return result; +} + +int main(){ + int n, m, x; + int start, end, time; + cin >> n >> m >> x; + + // 연결리스트 + vector> nodes(n+1, vector(0)); + + // 입력 + for(int i=0; i> start >> end >> time; + nodes[start].push_back({end, time}); + } + // 연산과 출력 + cout << result(nodes, x, n); +} \ 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/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 00000000..4c5d94cf --- /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,87 @@ +#include +#include + +using namespace std; + +// 평면의 각 칸 길이 +const int SIZE = 100; + +// 방향: 우(0), 상(1), 좌(2), 하(3) +int dy[4] = { 0, -1, 0, 1 }; +int dx[4] = { 1, 0, -1, 0 }; + +// 1x1 정사각형 개수 계산 +int cntSquares(vector>& plane) { + // ans 초기화 + int ans = 0; + // 전체 평면을 살펴보면서 + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + // 네 꼭짓점이 모두 드래곤 커브의 일부인 정사각형을 발견하면 + if (plane[i][j] && plane[i + 1][j] && plane[i][j + 1] && plane[i + 1][j + 1]) { + // 정답 값을 1 증가시켜준다. + ans++; + } + } + } + return ans; +} + +// 평면에 드래곤 커브를 표시 +void drawDragonCurve(vector>& plane, int x, int y, int d, int g) { + vector direct; // 방향 저장 + plane[y][x] = plane[y + dy[d]][x + dx[d]] = true; // 평면에 표시 (초기화) + // x, y좌표 갱신 + x += dx[d]; + y += dy[d]; + // 방향 저장 + direct.push_back(d); + while (g--) { // 1 ~ g 세대 + int size_d = direct.size(); + for (int j = size_d - 1; j >= 0; j--) { // 방향 계산 + // 다음 방향 계산 + int next_d = (direct[j] + 1) % 4; + // x,y 좌표 갱신 + x += dx[next_d]; + y += dy[next_d]; + plane[y][x] = true; // 평면에 표시 + // 방향 저장 + direct.push_back(next_d); + } + } +} + +/* +* 규칙 +* 0 세대: 0 +* 1 세대: 0 1 +* 2 세대: 0 1 2 1 +* 3 세대: 0 1 2 1 2 3 2 1 +* ... +* N 세대: concat((N-1세대), ((N-1세대 거꾸로) + 1)%4) +* 평면(좌측 상단이 (0, 0))에 드래곤 커브를 그린 후 정사각형의 개수를 계산 +* 드래곤 커브는 평면 밖으로 나가지 않음으로 범위를 확인할 필요 없음 +* 1. 0 세대의 드래곤 커브를 먼저 저장 (초기 조건) +* 2. 세대를 거듭하면서 드래곤 커브를 그림 (규칙을 파악하는 것이 중요) +* 3. 드래곤 커브가 그려진 평면 상의 정사각형의 개수 계산 (네 꼭짓점 확인) +*/ + +int main() +{ + // 변수 선언 + int n, x, y, d, g; + // 전체 평면 + vector> plane(SIZE + 1, vector(SIZE + 1, false)); // 평면 + // 입력 + cin >> n; + // 연산 & 출력 + while (n--) { // n개의 드래곤 커브 그리기 + // 입력받기 + cin >> x >> y >> d >> g; + // 드래곤 커브 평면에 반영하기 + drawDragonCurve(plane, x, y, d, g); + } + // 네 꼭짓점이 드래곤 커브의 일부인 정사각형 구해서 출력 + cout << cntSquares(plane) << '\n'; + return 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/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 00000000..8842ce1a --- /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,56 @@ +#include "iostream" +#include "vector" +#include "algorithm" + +using namespace std; + +const int INF = 9999999; // 최대 n-1개의 간선을 지나므로 n * (가중치 최대값) + +int floydWarshall(int n, vector> &graph) { + for (int k = 1; k <= n; k++) { // 중간 정점 + for (int i = 1; i <= n; i++) { // 출발 정점 + for (int j = 1; j <= n; j++) { // 도착 정점 + // 중간에 k를 거쳐서 i에서 j로 갈 때의 비용 + int cost = graph[i][k] + graph[k][j]; + // 더 짧은 경로 선택 + graph[i][j] = min(graph[i][j], cost); + } + } + } + + int count =0, result =0; + for(int i=1; i<=n; i++){ + for(int j=1; j<=n; j++){ + // 조건을 만족한다면 i와 j 사이의 대소 관계는 서로 알 수 있다는 뜻 + if(graph[i][j] != INF || graph[j][i] != INF){ + count++; + } + } + // 서로의 키 대소관계를 아는 사람의 수가 n-1 + 자기 자신은 항상 알수 있으므로 1 + // 즉 count가 n이라면 자신의 키 순위를 알 수 있을 것이다. + if(count == n){ + result++; + } + count =0; + } + return result; +} + +int main() { + int n, m; + int taller, smaller; + + // 입력 + 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 >> taller >> smaller; + graph[taller][smaller] = 1; + } + + // 연산 및 출력 + cout << floydWarshall(n, graph); +} \ No newline at end of file