-
Notifications
You must be signed in to change notification settings - Fork 0
[최단경로] 11월 7일 #15
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
base: master
Are you sure you want to change the base?
The head ref may contain hidden characters: "1102_\uCD5C\uB2E8\uACBD\uB85C"
[최단경로] 11월 7일 #15
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,76 @@ | ||
/* | ||
* 킹 : https://www.acmicpc.net/problem/1063 | ||
*/ | ||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
bool map[9][9]; | ||
//R,L,B,T,RT,LT,RB,LB 순으로 방향벡터 | ||
int dr[8] = {0, 0, 1, -1, -1, -1, 1, 1}; | ||
int dc[8] = {1, -1, 0, 0, 1, -1, 1, -1}; | ||
|
||
int direction(string op) { | ||
if (op == "R") { | ||
return 0; | ||
} else if (op == "L") { | ||
return 1; | ||
} else if (op == "B") { | ||
return 2; | ||
} else if (op == "T") { | ||
return 3; | ||
} else if (op == "RT") { | ||
return 4; | ||
} else if (op == "LT") { | ||
return 5; | ||
} else if (op == "RB") { | ||
return 6; | ||
} else if (op == "LB") { | ||
return 7; | ||
} | ||
} | ||
|
||
int main() { | ||
char king_alpha, rock_alpha; | ||
int king_r, king_c, rock_r, rock_c; | ||
int num; | ||
cin >> king_alpha >> king_r >> rock_alpha >> rock_r >> num; | ||
|
||
king_r = abs(9 - king_r); | ||
rock_r = abs(9 - rock_r); | ||
Comment on lines
+39
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. king_r과 rock_r은 1~8사이의 수 일테니 절댓값 함수는 없어도 괜찮겠네요! |
||
king_c = king_alpha - 'A' + 1; | ||
rock_c = rock_alpha - 'A' + 1; | ||
|
||
while (num--) { | ||
string op; | ||
int d; | ||
cin >> op; | ||
d = direction(op); //방향 인덱스 결정 | ||
int king_nr = king_r + dr[d]; | ||
int king_nc = king_c + dc[d]; | ||
if (king_nr > 8 || king_nr < 1 || king_nc > 8 || king_nc < 1) continue; //범위 확인 | ||
//이동 | ||
king_r = king_nr; | ||
king_c = king_nc; | ||
|
||
//돌이 있는 곳으로 갔는지 확인 | ||
if (king_r == rock_r && king_c == rock_c) { | ||
int rock_nr = rock_r + dr[d]; | ||
int rock_nc = rock_c + dc[d]; | ||
if (rock_nr > 8 || rock_nr < 1 || rock_nc > 8 || rock_nc < 1) continue; //범위 확인 | ||
//이동 | ||
rock_r = rock_nr; | ||
rock_c = rock_nc; | ||
} | ||
|
||
//여기선 마지막 좌표 출력이 잘 되는데 왜 어떤 테케에서만.... 정답 출력에서 값이 다르지? | ||
// cout << "king :" << king_r << " " << king_c << "\n"; | ||
// cout << "rock :" << rock_r << " " << rock_c << "\n\n"; | ||
} | ||
|
||
// while문 빠져나오고 이거 값이 달라짐 | ||
// cout << "king :" << king_r << " " << king_c << "\n"; | ||
// cout << "rock :" << rock_r << " " << rock_c << "\n\n"; | ||
|
||
cout << char(king_c + 64) << abs(9 - king_r) << "\n" << char(rock_c + 64) << abs(9 - rock_r) << "\n"; | ||
Comment on lines
+66
to
+75
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. 킹은 범위 안이고, 킹이 움직인 자리에 돌이 있어서 이동했을 때 만약 돌이 범위를 벗어났다면 어떻게 해야 할까요? 킹이 움직이는 게 맞을까요? 이 경우만 처리해주시면 주석 다신 부분 해결될 것 같아요! |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* 숨바꼭질 3 : https://www.acmicpc.net/problem/13549 | ||
*/ | ||
#include <iostream> | ||
#include <algorithm> | ||
#include <queue> | ||
|
||
using namespace std; | ||
#define MAX 100000 | ||
bool visited[MAX + 1]; | ||
int n, k; | ||
Comment on lines
+10
to
+11
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. visited는 bfs 함수에서만 사용하니 지역변수로 선언해도 괜찮겠네요~!!! |
||
|
||
int bfs(int time, int pos) { | ||
deque<pair<int, int>> dq; //bfs에서 큐에 넣을 땐 가중치(?) 같은 것이 한 번에 들어가는데 순간이동만 가중치가 0이므로, 큐 맨앞에 넣어줘야함 | ||
visited[pos] = true; | ||
Comment on lines
+14
to
+15
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. deque로 정점만 관리하는 방법이 있어요! visited 함수를 활용해서 방문처리와 함께 시간을 관리해보면 어떨까요? |
||
dq.push_back({time, pos}); | ||
while (!dq.empty()) { | ||
int curTime = dq.front().first; | ||
int curPos = dq.front().second; | ||
dq.pop_front(); | ||
|
||
if (curPos == k) return curTime; | ||
//2*x | ||
if (2 * curPos <= MAX && !visited[2 * curPos]) { | ||
visited[2 * curPos] = true; | ||
dq.push_front({curTime, 2 * curPos}); // 이동거리 (time)이 0이므로 front에 넣어줘야함!! | ||
} | ||
//x-1 | ||
if (curPos >= 1 && !visited[curPos - 1]) { | ||
visited[curPos - 1] = true; | ||
dq.push_back({curTime + 1, curPos - 1}); | ||
} | ||
|
||
//x+1 | ||
if (curPos <= MAX - 1 && !visited[curPos + 1]) { | ||
visited[curPos + 1] = true; | ||
dq.push_back({curTime + 1, curPos + 1}); | ||
} | ||
} | ||
} | ||
|
||
int main() { | ||
cin >> n >> k; | ||
cout << bfs(0, n) << "\n"; | ||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* 특정한 최단 경로 : https://www.acmicpc.net/problem/1504 | ||
*/ | ||
|
||
// 추가제출 하겠습니다. | ||
|
||
Comment on lines
+5
to
+6
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. 넵! 그래도 힌트 하나만 드릴께요...! 주어진 정점 2개를 시작 또는 도착 지점으로 생각하고, 여러 경로를 이어서 생각해보면 돼요! |
||
#include <iostream> | ||
#include <vector> | ||
#include <queue> | ||
|
||
using namespace std; | ||
const int MAX = 2147000000; | ||
|
||
int dijkstra(int start, int n, vector<vector<pair<int, int>>> &graph) { | ||
vector<int> dist(n + 1, MAX); | ||
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq; //최소 힙 // fisrt: 가중치, second: 정점 번호 | ||
|
||
//시작 위치 초기화 | ||
dist[start] = 0; | ||
pq.push({0, start}); | ||
|
||
while (!pq.empty()) { | ||
int w = pq.top().first; | ||
int node = pq.top().second; | ||
pq.pop(); | ||
|
||
//주어진 경로 반드시 이동? | ||
} | ||
|
||
} | ||
|
||
int main() { | ||
int n, e, a, b, c, v1, v2; | ||
cin >> n >> e; | ||
vector<vector<pair<int, int>>> graph(e + 1, vector<pair<int, int>>(0)); //인접 리스트 | ||
while (e--) { | ||
cin >> a >> b >> c; | ||
//무방향 그래프 | ||
graph[a].push_back({b, c}); //a에서 b까지 가는데 c의 가중치 | ||
graph[b].push_back({a, c}); //b에서 a까지 가는데 c의 가중치 | ||
} | ||
cin >> v1 >> v2; //반드시 지나야하는 정점... | ||
|
||
cout << dijkstra(1, n, graph); //1번에서 n번 정점으로 | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* 드래곤 커브 : https://www.acmicpc.net/problem/15685 | ||
*/ | ||
|
||
//추가제출 하겠습니다. | ||
|
||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
bool map[101][101]; | ||
|
||
//0,1,2,3 방향 | ||
int dr[4] = {0, -1, 0, 1}; | ||
int dc[4] = {1, 0, -1, 0}; | ||
|
||
/* | ||
* 드래곤 커브는 서로 겹칠 수 있다. | ||
*/ | ||
|
||
int main() { | ||
int n, x, y, d, g; | ||
cin >> n; | ||
|
||
while (n--) { | ||
cin >> x >> y >> d >> g; | ||
|
||
} | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* 녹색 옷 입은 애가 젤다지? : https://www.acmicpc.net/problem/4485 | ||
*/ | ||
|
||
#include <iostream> | ||
#include <vector> | ||
#include <queue> | ||
|
||
using namespace std; | ||
int n; | ||
const int MAX = 2147000000; | ||
Comment on lines
+10
to
+11
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. 최대값은 입력으로 주어진 범위를 보고 생각해보아도 좋아요! |
||
vector<vector<int>> map; | ||
int dr[4] = {-1, 0, 1, 0}; | ||
int dc[4] = {0, 1, 0, -1}; | ||
|
||
struct Loc { | ||
int w; //가중치 (도둑루피 크기) | ||
int r; //행 좌표 | ||
int c; //열 좌표 | ||
|
||
Loc(int ww, int rr, int cc) { | ||
w = ww; | ||
r = rr; | ||
c = cc; | ||
} | ||
|
||
bool operator<(const Loc &b) const { | ||
return w > b.w; //내림차순 (최소힙) | ||
} | ||
}; | ||
|
||
int dijkstra(int r, int c, vector<vector<int>> &map) { | ||
vector<vector<int>> dist(n, vector<int>(n, MAX)); // 초기엔 최대값으로 | ||
priority_queue<Loc> pq; | ||
|
||
//시작 위치 초기화 (r=0,c=0) | ||
pq.push(Loc(map[r][c], r, c)); | ||
dist[r][c] = map[r][c]; | ||
while (!pq.empty()) { | ||
int cur_w = pq.top().w; | ||
int cur_r = pq.top().r; | ||
int cur_c = pq.top().c; | ||
pq.pop(); | ||
//if (cur_w > dist[cur_r][cur_c]) continue; //이미 확인했던 정점 | ||
for (int d = 0; d < 4; d++) { | ||
int nr = cur_r + dr[d]; | ||
int nc = cur_c + dc[d]; | ||
if (nr < 0 || nr > n - 1 || nc < 0 || nc > n - 1) continue; | ||
int nw = cur_w + map[nr][nc]; //연결된 정점까지의 거리 | ||
if (dist[nr][nc] > nw) { //더 짧은 경로로 갈 수 있으면 | ||
dist[nr][nc] = nw; | ||
pq.push(Loc(nw, nr, nc)); | ||
} | ||
} | ||
} | ||
return dist[n - 1][n - 1]; | ||
} | ||
|
||
int main() { | ||
int stage = 1; | ||
while (true) { | ||
cin >> n; | ||
if (n == 0) break; | ||
map.assign(n, vector<int>(n, 0)); | ||
for (int i = 0; i < n; i++) { | ||
for (int j = 0; j < n; j++) { | ||
cin >> map[i][j]; | ||
} | ||
} | ||
cout << "Problem " << stage++ << ": " << dijkstra(0, 0, map) << "\n"; | ||
} | ||
|
||
} |
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.
p2. 함수 사용도 좋지만, "LB"에 접근하기까지 8번 연산을 해야 하니 검색에 O(logN)이 걸리는 map을 사용해봐도 좋을 것 같아요!