-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[동적계획법과 최단거리 역추적]11월 15일 #15
base: main
Are you sure you want to change the base?
The head ref may contain hidden characters: "\uB3D9\uC801\uACC4\uD68D\uBC95\uACFC-\uCD5C\uB2E8\uAC70\uB9AC-\uC5ED\uCD94\uC801"
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// | ||
// Created by LG on 2021-11-13. | ||
// | ||
#include <iostream> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
const int INF = 1e7; | ||
typedef pair<int, int> ci; | ||
|
||
void floydWarshall(int n, vector<vector<int>> &graph, vector<vector<ci>> &table){ | ||
for(int k=1; k<=n; k++){ | ||
for(int i=1; i<=n; i++){ | ||
for(int j=1; j<=n; j++){ | ||
int dist = graph[i][k] + graph[k][j]; | ||
if(dist < graph[i][j]){ | ||
graph[i][j] = dist; | ||
table[i][j] = {table[i][k].first+table[k][j].first, table[i][k].second}; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
int main(){ | ||
|
||
int n, m, a, b, c; | ||
cin >> n >> m; | ||
vector<vector<int>> graph(n+1, vector<int>(n+1, INF)); | ||
vector<vector<ci>> table(n+1, vector<ci>(n+1)); | ||
for(int i=1; i<=n; i++) | ||
graph[i][i] = 0; | ||
|
||
while(m--){ | ||
cin >> a >> b >> c; | ||
if(graph[a][b] > c){ | ||
graph[a][b] = c; | ||
table[a][b] = {1, b}; | ||
} | ||
} | ||
|
||
floydWarshall(n, graph, table); | ||
|
||
for(int i=1; i<=n; i++){ | ||
for(int j=1; j<=n; j++){ | ||
if(graph[i][j] == INF) | ||
cout << '0' << ' '; | ||
else | ||
cout << graph[i][j] << ' '; | ||
} | ||
cout << '\n'; | ||
} | ||
|
||
for(int i=1; i<=n; i++){ | ||
for(int j=1; j<=n; j++){ | ||
if(graph[i][j] == INF || graph[i][j] == 0) | ||
cout << '0'; | ||
else{ | ||
cout << table[i][j].first+1 << ' ' << i << ' '; | ||
int t = table[i][j].second; | ||
while(t != j){ | ||
cout << t << ' '; | ||
t = table[t][j].second; | ||
} | ||
cout << j; | ||
} | ||
cout << '\n'; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// | ||
// Created by LG on 2021-11-11. | ||
// | ||
#include <iostream> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
typedef pair<int, int> ci; | ||
|
||
int main() { | ||
int n; | ||
cin >> n; | ||
vector<ci> count(n + 1, {0, 0}); | ||
|
||
if (n % 3 == 0) { | ||
count[n / 3] = {1, n}; | ||
} | ||
if (n % 2 == 0) { | ||
count[n / 2] = {1, n}; | ||
} | ||
count[n - 1] = {1, n}; | ||
|
||
for (int i = n - 1; i > 1; i--) { | ||
if (count[i].first == 0) | ||
continue; | ||
if (i % 3 == 0) { | ||
if (count[i / 3].first == 0) | ||
count[i / 3] = {count[i].first + 1, i}; | ||
else { | ||
if (count[i / 3].first > count[i].first + 1) | ||
count[i / 3] = {count[i].first + 1, i}; | ||
} | ||
Comment on lines
+28
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p2. count[i].first의 값을 문제의 입력범위보다 큰 상수를 선언해서 초기화하면 현재 코드를 하나로 합칠 수 있겠네요!! 나머지 i % 2 와 i - 1에 대해서도요~! 더불어 메인 연산을 하고 있는 부분은 함수화를 하면 더 좋을 것 같아요! |
||
} | ||
if (i % 2 == 0) { | ||
if (count[i / 2].first == 0) | ||
count[i / 2] = {count[i].first + 1, i}; | ||
else { | ||
if (count[i / 2].first > count[i].first + 1) | ||
count[i / 2] = {count[i].first + 1, i}; | ||
} | ||
} | ||
if (count[i - 1].first == 0) | ||
count[i - 1] = {count[i].first + 1, i}; | ||
else { | ||
if (count[i - 1].first > count[i].first + 1) | ||
count[i - 1] = {count[i].first + 1, i}; | ||
} | ||
} | ||
|
||
int ans = count[1].first; | ||
cout << ans << '\n'; | ||
vector<int> path(ans + 1); | ||
path[0] = 1; | ||
for (int i = 0; i < ans; i++) | ||
path[i + 1] = count[path[i]].second; | ||
Comment on lines
+55
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p2. 역추적 부분도 함수화할 수 있겠네요~! |
||
|
||
for (int i = ans; i >= 0; i--) | ||
cout << path[i] << ' '; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// | ||
// Created by LG on 2021-11-13. | ||
// | ||
#include <iostream> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
const int INF = 2*1e5; | ||
|
||
void floydWarshall(int n, vector<vector<int>> graph, vector<vector<int>> &table){ | ||
for(int k=1; k<=n; k++){ | ||
for(int i=1; i<=n; i++){ | ||
for(int j=1; j<=n; j++){ | ||
int dist = graph[i][k] + graph[k][j]; | ||
if(dist < graph[i][j]){ | ||
graph[i][j] = dist; | ||
table[i][j] = table[i][k]; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
int main(){ | ||
int n, m, u, v, w; | ||
cin >> n >> m; | ||
vector<vector<int>> graph(n+1, vector<int>(n+1, INF)); | ||
vector<vector<int>> table(n+1, vector<int>(n+1)); | ||
for(int i=0; i<n; i++) | ||
graph[i][i] = 0; | ||
|
||
while(m--){ | ||
cin >> u >> v >> w; | ||
if(graph[u][v] > w){ | ||
graph[u][v] = w; | ||
graph[v][u] = w; | ||
table[u][v] = v; | ||
table[v][u] = u; | ||
} | ||
Comment on lines
+35
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p3. 혹시 모를 중복 간선을 항상 걸러주는 것도 좋지만, 문제에서 주어진 정점과 간선의 최대범위를 보고, 정점에 대한 최대 간선을 계산해보면 중복 간선이 들어오는지 안 들어오는지 파악할 수 있어요~! 그래도 코딩테스트에선 시간이 없을 수 있으니 항상 걸러주는 것도 괜찮겠네요! |
||
} | ||
|
||
floydWarshall(n, graph, table); | ||
|
||
for(int i=1; i<=n; i++){ | ||
for(int j=1; j<=n; j++){ | ||
if(i==j) | ||
cout << '-' << ' '; | ||
else | ||
cout << table[i][j] << ' '; | ||
} | ||
cout << '\n'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#include <iostream> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
bool five(int color, int i, int j, vector<vector<int>> board){ | ||
bool check = true; | ||
for(int k = 1; k < 5; k++){ | ||
if(j>15 || board[i][j+k] != color){ | ||
check = false; | ||
break; | ||
} | ||
} | ||
if(check){ | ||
if((j==1 || board[i][j-1] != color) && (j==15 || board[i][j+5] != color)) | ||
return true; | ||
} | ||
|
||
check = true; | ||
for (int k = 1; k < 5; k++) { | ||
if(i>15 || board[i+k][j] != color){ | ||
check = false; | ||
break; | ||
} | ||
} | ||
if(check){ | ||
if((i==1 || board[i-1][j] != color) && (i==15 || board[i+5][j] != color)) | ||
return true; | ||
} | ||
|
||
check = true; | ||
for(int k = 1; k < 5; k++){ | ||
if(i>15 || j>15 || board[i+k][j+k] != color){ | ||
check = false; | ||
break; | ||
} | ||
} | ||
if(check){ | ||
if((i==1 || j==1 || board[i-1][j-1] != color) && (i==15 || j==15 || board[i+5][j+5] != color)) | ||
return true; | ||
} | ||
|
||
check = true; | ||
for(int k=1; k<5; k++){ | ||
if(i<5 || j>15 || board[i-k][j+k] != color){ | ||
check = false; | ||
break; | ||
} | ||
} | ||
if(check){ | ||
if((i==1 || j==19 || board[i+1][j-1] != color) && (i==5 || j==15 || board[i-5][j+5] != color)) | ||
return true; | ||
} | ||
Comment on lines
+8
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p2. 가능한 방향에 대한 배열을 미리 만든 후, 반복문을 통해 관리하면 현재 연산을 훨씬 짧게 줄일 수 있어요! 방향 배열을 다루는 문제는 지금까지 꽤 해봤어요. 한 번 수정해볼까요! |
||
|
||
return false; | ||
|
||
} | ||
|
||
int main() { | ||
|
||
vector<vector<int>> board(20, vector<int>(20)); | ||
for(int i=1; i<20; i++){ | ||
Comment on lines
+61
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p2. 20은 앞으로 계속 사용할 테니, 헷갈리지 않게 상수로 선언하고 사용해주시는 게 좋아요! |
||
for(int j=1; j<20; j++){ | ||
cin >> board[i][j]; | ||
} | ||
} | ||
|
||
bool check; | ||
for(int i=1; i<20; i++){ | ||
for(int j=1; j<20; j++){ | ||
int color = board[i][j]; | ||
if(color == 1) { | ||
check = five(1, i, j, board); | ||
if(check) { | ||
cout << color << '\n' << i << ' ' << j; | ||
return 0; | ||
} | ||
} | ||
else if(color == 2){ | ||
check = five(2, i, j, board); | ||
if(check){ | ||
cout << color << '\n' << i << ' ' << j; | ||
return 0; | ||
} | ||
} | ||
Comment on lines
+72
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. p2. 이 부분은 color만 다르고 연산은 중복되니, 하나로 합칠 수 있겠네요~! |
||
} | ||
} | ||
|
||
cout << 0; | ||
return 0; | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p3. 우선 택배 문제를 활용해서 경로 추적해주신 거 아주 좋아요!! 👍
지금처럼 크기를 따로 table에 저장하며 풀어주신 것도 좋지만, 경로를 추적한 결과값을 배열에 담은 후 나중에 배열 사이즈와 원소를 출력해도 괜찮겠네요! 그럼 table에 들어가는 메모리를 줄일 수 있을 거예요.