From f545180617e6c5525c3b0ef402f27a0cca32729f Mon Sep 17 00:00:00 2001 From: aqswa <69039161+aqswa@users.noreply.github.com> Date: Mon, 29 Nov 2021 23:54:17 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[=EC=9C=A0=EB=8B=88=EC=98=A8=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=B8=EB=93=9C]11=EC=9B=94=2029=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- [union find]1129/1043.cpp | 78 ++++++++++++++++++++++++++++++++++++++ [union find]1129/18111.cpp | 58 ++++++++++++++++++++++++++++ [union find]1129/1976.cpp | 74 ++++++++++++++++++++++++++++++++++++ [union find]1129/20040.cpp | 48 +++++++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 [union find]1129/1043.cpp create mode 100644 [union find]1129/18111.cpp create mode 100644 [union find]1129/1976.cpp create mode 100644 [union find]1129/20040.cpp diff --git a/[union find]1129/1043.cpp b/[union find]1129/1043.cpp new file mode 100644 index 0000000..cc99a40 --- /dev/null +++ b/[union find]1129/1043.cpp @@ -0,0 +1,78 @@ +// +// Created by LG on 2021-11-27. +// +#include +#include + +using namespace std; + +vector parent; +vector truth; + +int findParent(int node){ + if(parent[node] < 0) + return node; + return parent[node] = findParent(parent[node]); +} + +void unionInput(int x, int y){ + int xp = findParent(x); + int yp = findParent(y); + + if(xp == yp) + return; + if(truth[xp] || truth[yp]) + truth[xp] = truth[yp] = true; + if(parent[xp] < parent[yp]){ + parent[xp] += parent[yp]; + parent[yp] = xp; + } + else{ + parent[yp] += parent[xp]; + parent[xp] = yp; + } +} + +int main(){ + int n, m, k; + cin >> n >> m >> k; + int cnt = m; + parent.assign(n+1, -1); + truth.assign(n+1, false); + vector> party(m, vector()); + + for(int i=0; i> p; + truth[p] = true; + } + + for(int i=0; i> t; + party[i].assign(t, 0); + + for(int j=0; j> p; + party[i][j] = p; + } + + for(int j=0; j +#include +#include + +using namespace std; + +const int MAX = INT_MAX; + +int main(){ + int n, m, b; + cin >> n >> m >> b; + + vector> height(n, vector(m, 0)); + int min_h = 256; + int max_h = 0; + for(int i=0; i> height[i][j]; + if(height[i][j] < min_h) + min_h = height[i][j]; + if(height[i][j] > max_h) + max_h = height[i][j]; + } + } + + int ans_time = MAX; + int ans_h; + while(min_h <= max_h){ + int time = 0; + int b_temp = b; + for(int i=0; i min_h){ + int diff = height[i][j] - min_h; + time += 2*diff; + b_temp += diff; + } + else if(height[i][j] < min_h){ + int diff = min_h - height[i][j]; + time += diff; + b_temp -= diff; + } + } + } + + if(b_temp >= 0 && time <= ans_time) { + ans_time = time; + ans_h = min_h; + } + min_h++; + } + + cout << ans_time << ' ' << ans_h; + return 0; +} diff --git a/[union find]1129/1976.cpp b/[union find]1129/1976.cpp new file mode 100644 index 0000000..80a0596 --- /dev/null +++ b/[union find]1129/1976.cpp @@ -0,0 +1,74 @@ +// +// Created by LG on 2021-11-28. +// +#include +#include + +using namespace std; + +vector parent; + +int findParent(int node){ + if(parent[node] < 0) + return node; + else + return parent[node] = findParent(parent[node]); +} + +void unionInput(int x, int y){ + int xp = findParent(x); + int yp = findParent(y); + + if(xp == yp) + return; + if(parent[xp] < parent[yp]){ + parent[xp] += parent[yp]; + parent[yp] = xp; + } + else{ + parent[yp] += parent[xp]; + parent[xp] = yp; + } + +} + +bool result(int m, vector route){ + for(int i=0; i> n >> m; + parent.assign(n+1, -1); + vector> cities(n+1, vector(n+1)); + vector route(m, 0); + for(int i=1; i<=n; i++){ + for(int j=1; j<=n; j++){ + cin >> cities[i][j]; + } + } + + for(int i=0; i> route[i]; + } + + for(int i=1; i<=n; i++){ + for(int j=i+1; j<=n; j++){ + if(cities[i][j]==1) + unionInput(i, j); + } + } + + if(result(m, route)) + cout << "YES"; + else + cout << "NO"; + + return 0; +} diff --git a/[union find]1129/20040.cpp b/[union find]1129/20040.cpp new file mode 100644 index 0000000..2ecaa70 --- /dev/null +++ b/[union find]1129/20040.cpp @@ -0,0 +1,48 @@ +// +// Created by LG on 2021-11-27. +// +#include +#include + +using namespace std; + +vector parent; + +int findParent(int node){ + if(parent[node] < 0) + return node; + return parent[node] = findParent(parent[node]); +} + +bool unionInput(int x, int y){ + int xp = findParent(x); + int yp = findParent(y); + + if(xp == yp){ + return true; + } + if(parent[xp] < parent[yp]){ + parent[xp] += parent[yp]; + parent[yp] = xp; + } + else{ + parent[yp] += parent[xp]; + parent[xp] = yp; + } + return false; +} + +int main(){ + int n, m, a, b; + cin >> n >> m; + parent.assign(n, -1); + for(int i=0; i> a >> b; + if(unionInput(a, b)) { + cout << i+1; + return 0; + } + } + cout << '0'; + return 0; +} From fd32d249ff182edfec0cd765dbeaf583c00ae4cf Mon Sep 17 00:00:00 2001 From: aqswa <69039161+aqswa@users.noreply.github.com> Date: Tue, 30 Nov 2021 22:38:31 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[=EC=9C=A0=EB=8B=88=EC=98=A8=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8]11=EC=9B=94=2030=EC=9D=BC(=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=EC=A0=9C=EC=B6=9C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- [union find]1129/16236.cpp | 111 +++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 [union find]1129/16236.cpp diff --git a/[union find]1129/16236.cpp b/[union find]1129/16236.cpp new file mode 100644 index 0000000..65a9c91 --- /dev/null +++ b/[union find]1129/16236.cpp @@ -0,0 +1,111 @@ +// +// Created by LG on 2021-11-30. +// +#include //표준 입출력 스트림 +#include //vector +#include //queue +#include //sort + +using namespace std; //표준 네임스페이스 +const int INF = 401; //최대 이동거리 400 +typedef pair ci; //pair 타입을 ci로 정의 + +pair nextPos(int n, int shark_size, ci &shark, vector> &board) { + int dr[4] = {-1, 1, 0, 0}; //행의 상 하 좌 우 + int dc[4] = {0, 0, -1, 1}; //열의 상 하 좌 우 + + int min_dist = INF; //최소 이동거리를 최대로 초기화 + queue q; //상어가 갈 수 있는 곳 + vector> visited(n, vector(n, 0)); //상어의 방문 여부 + vector list; //상어가 먹을 수 있는 물고기들의 위치 + + visited[shark.first][shark.second] = 1; //상어가 시작한 위치는 방문 표시함 + q.push(shark); //시작 위치 queue에 push함. + while (!q.empty()) { //큐가 빌 때까지 + int row = q.front().first; //행 위치 입력 + int col = q.front().second; //열 위치 입력 + int dist = visited[row][col]; //visited에 입력된 1 큰 값으로 초기화함. + q.pop(); //큐에서 팝 함. + + if (dist >= min_dist) //최단거리 이상은 탐색할 필요 없음 + continue; //while문 계속 함. + for (int i = 0; i < 4; i++) { //상하좌우 4번 + int nr = row + dr[i]; //행 갱신함 + int nc = col + dc[i]; //열 갱신함 + if (nr < 0 || nr >= n || nc < 0 || nc >= n || visited[nr][nc] || board[nr][nc] > shark_size) //범위 밖이거나 시작 위치이거나 더 크면 + continue; //while문 계속 함. + + visited[nr][nc] = visited[row][col] + 1; //범위 내에 방문할 수 있는 칸이면 현재 거리에 한 칸 더한 거리 입력함. + if (board[nr][nc] && board[nr][nc] < shark_size) { //먹을 수 있는 물고기 발견 + list.emplace_back(nr, nc); //list에 입력함. + min_dist = visited[nr][nc]; //최단거리 갱신함. + continue; //while문 계속 함. + } + q.push({nr, nc}); //방문할 수 있는데 먹을 수 없는 칸 push함. + } + } + + if (list.empty()) //상어가 갈 수 있는 곳이 없음 + return {min_dist, {-1, -1}}; //갱신되지 않은 min_dist 리턴함. + + sort(list.begin(), list.end(), [](const ci &p1, const ci &p2) { //정렬 + if (p1.first != p2.first) //행이 다르면 + return p1.first < p2.first; //행 기준 오름차순 + return p1.second < p2.second; //행이 같다면 열 기준 오름차순 + }); + return {min_dist - 1, list[0]}; //1부터 시작했으므로 -1한 거리와 가까운 칸 중 가장 위, 왼쪽 칸 반환 +} + +int simulation(int n, pair &shark, vector> &board) { + int ans = 0, size = 2, cnt = 0; //시간 입력할 변수, 상어 크기, 먹은 물고기 수 + while (true) { //반복문 + pair result = nextPos(n, size, shark, board); //상어가 이동할 위치 찾음 + if (result.first == INF) //더 이상 먹을 수 있는 물고기가 공간에 없음 + break; //while문 탈출 + ans += result.first; //최단 거리 더함. + cnt++; //먹은 물고기 수 늘림. + if (cnt == size) { //상어 크기 증가 + cnt = 0; //먹은 물고기 초기화하고 + size++; //상어 크기 증가함. + } + + //상어 이동 + ci pos = result.second; //상어 위치 잠시 저장함. + board[shark.first][shark.second] = 0; // 아무것도 없는 칸으로 표시함. + shark = pos; //상어 위치 갱신함. + } + return ans; //걸린 초 리턴함. +} + +/** + * 1. 상어로부터 가장 가까운 거리에 있는 모든 물고기 탐색 (BFS) + * 2. 우선순위 조건에 맞추어 먹으러 갈 물고기 확정 + * 탐색하는 방향에 우선순위를 두는 걸로 해결되지 않음! (예제 입력 4) 정렬 필요 + * 3. 상어가 이동할 수 있는 곳이 없을 때까지 BFS 탐색 반복 + * + * 입력 범위가 작기 때문에 매번 BFS 탐색을 반복해도 시간 초과 X + * 가능한 물고기의 최대 마리 수 : 399마리 + * 최대 BFS 탐색 횟수 : 399회, 1회 탐색마다 while 문은 최대 400회 미만으로 순회 + * 총 연산 횟수 약 160000번으로 충분히 가능 + * + * 해설 : https://myunji.tistory.com/378 + * *글 자체는 별로 도움이 안되고...그냥 리팩토링하면 코드가 이렇게 되는구나 정도만 봐주세요 + */ +int main() { + int n; //공간 크기 + pair shark_pos; //상어 위치 변수 + + //입력 + cin >> n; //공간 크기 입력 + vector> board(n, vector(n)); //공간 정보 입력 벡터 + for (int i = 0; i < n; i++) { //n열 + for (int j = 0; j < n; j++) { //n행 + cin >> board[i][j]; //물고기 정보 입력 받음 + if (board[i][j] == 9) //상어의 초기 위치 + shark_pos = make_pair(i, j); //상어라면 위치 입력 받음 + } + } + + //연산 & 출력 + cout << simulation(n, shark_pos, board); +} From c97c03a33e79f99fad8f711f293b530a1ce28488 Mon Sep 17 00:00:00 2001 From: aqswa <69039161+aqswa@users.noreply.github.com> Date: Tue, 30 Nov 2021 22:41:41 +0900 Subject: [PATCH 3/3] Delete 16236.cpp --- [union find]1129/16236.cpp | 111 ------------------------------------- 1 file changed, 111 deletions(-) delete mode 100644 [union find]1129/16236.cpp diff --git a/[union find]1129/16236.cpp b/[union find]1129/16236.cpp deleted file mode 100644 index 65a9c91..0000000 --- a/[union find]1129/16236.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// Created by LG on 2021-11-30. -// -#include //표준 입출력 스트림 -#include //vector -#include //queue -#include //sort - -using namespace std; //표준 네임스페이스 -const int INF = 401; //최대 이동거리 400 -typedef pair ci; //pair 타입을 ci로 정의 - -pair nextPos(int n, int shark_size, ci &shark, vector> &board) { - int dr[4] = {-1, 1, 0, 0}; //행의 상 하 좌 우 - int dc[4] = {0, 0, -1, 1}; //열의 상 하 좌 우 - - int min_dist = INF; //최소 이동거리를 최대로 초기화 - queue q; //상어가 갈 수 있는 곳 - vector> visited(n, vector(n, 0)); //상어의 방문 여부 - vector list; //상어가 먹을 수 있는 물고기들의 위치 - - visited[shark.first][shark.second] = 1; //상어가 시작한 위치는 방문 표시함 - q.push(shark); //시작 위치 queue에 push함. - while (!q.empty()) { //큐가 빌 때까지 - int row = q.front().first; //행 위치 입력 - int col = q.front().second; //열 위치 입력 - int dist = visited[row][col]; //visited에 입력된 1 큰 값으로 초기화함. - q.pop(); //큐에서 팝 함. - - if (dist >= min_dist) //최단거리 이상은 탐색할 필요 없음 - continue; //while문 계속 함. - for (int i = 0; i < 4; i++) { //상하좌우 4번 - int nr = row + dr[i]; //행 갱신함 - int nc = col + dc[i]; //열 갱신함 - if (nr < 0 || nr >= n || nc < 0 || nc >= n || visited[nr][nc] || board[nr][nc] > shark_size) //범위 밖이거나 시작 위치이거나 더 크면 - continue; //while문 계속 함. - - visited[nr][nc] = visited[row][col] + 1; //범위 내에 방문할 수 있는 칸이면 현재 거리에 한 칸 더한 거리 입력함. - if (board[nr][nc] && board[nr][nc] < shark_size) { //먹을 수 있는 물고기 발견 - list.emplace_back(nr, nc); //list에 입력함. - min_dist = visited[nr][nc]; //최단거리 갱신함. - continue; //while문 계속 함. - } - q.push({nr, nc}); //방문할 수 있는데 먹을 수 없는 칸 push함. - } - } - - if (list.empty()) //상어가 갈 수 있는 곳이 없음 - return {min_dist, {-1, -1}}; //갱신되지 않은 min_dist 리턴함. - - sort(list.begin(), list.end(), [](const ci &p1, const ci &p2) { //정렬 - if (p1.first != p2.first) //행이 다르면 - return p1.first < p2.first; //행 기준 오름차순 - return p1.second < p2.second; //행이 같다면 열 기준 오름차순 - }); - return {min_dist - 1, list[0]}; //1부터 시작했으므로 -1한 거리와 가까운 칸 중 가장 위, 왼쪽 칸 반환 -} - -int simulation(int n, pair &shark, vector> &board) { - int ans = 0, size = 2, cnt = 0; //시간 입력할 변수, 상어 크기, 먹은 물고기 수 - while (true) { //반복문 - pair result = nextPos(n, size, shark, board); //상어가 이동할 위치 찾음 - if (result.first == INF) //더 이상 먹을 수 있는 물고기가 공간에 없음 - break; //while문 탈출 - ans += result.first; //최단 거리 더함. - cnt++; //먹은 물고기 수 늘림. - if (cnt == size) { //상어 크기 증가 - cnt = 0; //먹은 물고기 초기화하고 - size++; //상어 크기 증가함. - } - - //상어 이동 - ci pos = result.second; //상어 위치 잠시 저장함. - board[shark.first][shark.second] = 0; // 아무것도 없는 칸으로 표시함. - shark = pos; //상어 위치 갱신함. - } - return ans; //걸린 초 리턴함. -} - -/** - * 1. 상어로부터 가장 가까운 거리에 있는 모든 물고기 탐색 (BFS) - * 2. 우선순위 조건에 맞추어 먹으러 갈 물고기 확정 - * 탐색하는 방향에 우선순위를 두는 걸로 해결되지 않음! (예제 입력 4) 정렬 필요 - * 3. 상어가 이동할 수 있는 곳이 없을 때까지 BFS 탐색 반복 - * - * 입력 범위가 작기 때문에 매번 BFS 탐색을 반복해도 시간 초과 X - * 가능한 물고기의 최대 마리 수 : 399마리 - * 최대 BFS 탐색 횟수 : 399회, 1회 탐색마다 while 문은 최대 400회 미만으로 순회 - * 총 연산 횟수 약 160000번으로 충분히 가능 - * - * 해설 : https://myunji.tistory.com/378 - * *글 자체는 별로 도움이 안되고...그냥 리팩토링하면 코드가 이렇게 되는구나 정도만 봐주세요 - */ -int main() { - int n; //공간 크기 - pair shark_pos; //상어 위치 변수 - - //입력 - cin >> n; //공간 크기 입력 - vector> board(n, vector(n)); //공간 정보 입력 벡터 - for (int i = 0; i < n; i++) { //n열 - for (int j = 0; j < n; j++) { //n행 - cin >> board[i][j]; //물고기 정보 입력 받음 - if (board[i][j] == 9) //상어의 초기 위치 - shark_pos = make_pair(i, j); //상어라면 위치 입력 받음 - } - } - - //연산 & 출력 - cout << simulation(n, shark_pos, board); -}