www.acmicpc.net/problem/15481

 

15481번: 그래프와 MST

첫째 줄에 정점의 개수 N과 간선의 개수 M (2 ≤ N ≤ 200,000, N-1 ≤ M ≤ 200,000) 둘째 줄부터 M개의 줄에 간선의 정보 u, v, w가 주어진다. u와 v를 연결하는 간선의 가중치가 w라는 뜻이다. (1 ≤ u, v ≤

www.acmicpc.net

M개의 간선 정보가 들어오는데 i번째 간선을 포함한 MST를 출력하는 문제입니다.

 

우선 전체 MST를 구해줍니다.

그 다음 i번째 간선을 포함해주고 그 간선에 연결된 정점들의 경로에 있는 MST 간선을 하나 제거해야합니다.

이 경로를 순회해야 하기때문에 이를 LCA로 구합니다.

 

여기서 LCA를 구하기 전에 각 정점의 높이를 구해야하는데 인접 리스트를 MST 간선들만 가지고 구해줍니다.

그럼 u v 경로의 최대 간선을 구할 수 있습니다.

 

답은 mst - lca(u, v) + w을 출력해주시면 되고, 입력이 들어온 순서대로 출력해야하니 인덱스를 유지해야합니다.

 

정리하자면

1. 먼저 주어진 간선들로 MST를 구합니다.

2. MST에 사용된 간선들로 인접 리스트를 만들어줍니다.

3. 인접리스트의 depth를 구합니다.

4. 입력(간선 정보)이 들어왔던 순서대로 lca를 구해줍니다.

5. mst - lca(u, v) + w을 출력합니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <iostream>
#include <vector>
#include <algorithm>
#define MAX 200000
#define LOG 20
using namespace std;
typedef long long ll;
 
typedef struct edge {
    int u;
    int v;
    ll w;
}edge;
 
vector<pair<int, ll> > list[MAX + 1];
vector<edge> v, nv;
pair<int, ll> lcaParent[MAX + 1][LOG];
int mstParent[MAX + 1], depth[MAX + 1];
bool visit[MAX + 1];
ll mst;
int N, M, cnt;
 
bool cmp(edge a, edge b) {
    return a.w < b.w;
}
 
void dfs(int v, int d) {
    depth[v] = d;
    visit[v] = true;
 
    for (int i = 0; i < list[v].size(); i++) {
        int next = list[v][i].first;
        ll w = list[v][i].second;
 
        if (visit[next]) continue;
        lcaParent[next][0= { v,w };
        dfs(next, d + 1);
    }
}
 
int find(int v) {
    if (mstParent[v] == v) return v;
    return mstParent[v] = find(mstParent[v]);
}
 
void Union(int x, int y, ll w) {
    int a = find(x);
    int b = find(y);
 
    if (a == b) return;
    list[x].push_back({ y,w });
    list[y].push_back({ x,w });
    mstParent[b] = a;
    mst += w;
    cnt++;
}
 
void makeMst() {
    for (int i = 0; i < M; i++) {
        int x = nv[i].u;
        int y = nv[i].v;
        ll w = nv[i].w;
 
        Union(x, y, w);
        if (cnt == N - 1break;
    }
}
 
void init() {
    for (int i = 1; i <= N; i++) {
        mstParent[i] = i;
    }
}
 
ll lca(int x, int y) {
    if (depth[x] > depth[y]) swap(x, y);
    ll ret = 0;
 
    for (int i = LOG - 1; i >= 0; i--) {
        if (depth[y] - depth[x] >= (1 << i)) {
            ret = max(ret, lcaParent[y][i].second);
            y = lcaParent[y][i].first;
        }
    }
 
    if (x == y) return ret;
 
    for (int i = LOG - 1; i >= 0; i--) {
        if (lcaParent[x][i].first == 0continue;
        if (lcaParent[x][i].first != lcaParent[y][i].first) {
            ret = max(ret, max(lcaParent[x][i].second, lcaParent[y][i].second));
 
            x = lcaParent[x][i].first;
            y = lcaParent[y][i].first;
        }
    }
 
    return max(ret, max(lcaParent[x][0].second, lcaParent[y][0].second));
}
 
void func() {
    dfs(11);
    for (int j = 1; j < LOG; j++) {
        for (int i = 1; i <= N; i++) {
            lcaParent[i][j].first = lcaParent[lcaParent[i][j - 1].first][j - 1].first;
            lcaParent[i][j].second = max(lcaParent[i][j - 1].second, lcaParent[lcaParent[i][j - 1].first][j - 1].second);
        }
    }
 
    for (int i = 0; i < M; i++) {
        int x = v[i].u;
        int y = v[i].v;
        ll w = v[i].w;
        ll sub = lca(x, y);
        cout << mst - sub + w << '\n';
    }
}
 
void input() {
    int x, y;
    ll w;
    cin >> N >> M;
    for (int i = 0; i < M; i++) {
        cin >> x >> y >> w;
        v.push_back({ x,y,w });
    }
    nv = v;
    sort(nv.begin(), nv.end(), cmp);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    init();
    makeMst();
    func();
 
    return 0;
}
cs

'algorithm > LCA' 카테고리의 다른 글

boj 3584 가장 가까운 공통 조상  (0) 2021.06.16
boj 1626 두 번째로 작은 스패닝 트리  (0) 2021.04.02
boj 15480 LCA와 쿼리  (0) 2021.02.14
boj 11438 LCA 2  (0) 2021.02.11
boj 11437 LCA  (0) 2021.02.11

www.acmicpc.net/problem/17609

 

17609번: 회문

각 문자열이 회문인지, 유사 회문인지, 둘 모두 해당되지 않는지를 판단하여 회문이면 0, 유사 회문이면 1, 둘 모두 아니면 2를 순서대로 한 줄에 하나씩 출력한다.

www.acmicpc.net

N이 10만개니 lcs로는 해결 못합니다..

 

투 포인터로 하나하나 확인해줍니다.

왼쪽 인덱스를 0, 오른쪽 인덱스를 ch.length - 1로 두고

문자열의 끝 단어끼리 비교를 합니다.

 

1. 끝 단어가 같을 때

- 왼쪽, 오른쪽 인덱스 모두 다음 인덱스를 확인합니다.

2. 끝 단어가 다를 때

- 왼쪽 인덱스를 옮겨줄 때와 오른쪽 인덱스를 옮겨줄 때를 각각 확인합니다.

저는 투포인터를 두번 사용하여 왼쪽 인덱스를 옮길 때, 오른쪽 인덱스를 옮길 때 다른 값의 min값으로 답을 출력하였습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static char ch[];
 
    static void func() {
        int l = 0;
        int r = ch.length - 1;
        int ans = 0;
        int cnt = 0;
        while (l < r) {
            if (ch[l] == ch[r]) {
                l++;
                r--;
            } else {
                cnt++;
                l++;
            }
 
            if (cnt == 2)
                break;
        }
        ans = cnt;
 
        l = 0;
        r = ch.length - 1;
        cnt = 0;
        while (l < r) {
            if (ch[l] == ch[r]) {
                l++;
                r--;
            } else {
                cnt++;
                r--;
            }
 
            if (cnt == 2)
                break;
        }
 
        ans = Math.min(ans, cnt);
        sb.append(ans).append("\n");
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        ch = st.nextToken().toCharArray();
    }
 
    public static void main(String[] args) throws Exception {
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            input();
            func();
        }
        System.out.println(sb.toString());
    }
}
cs

'algorithm > Two-Pointer' 카테고리의 다른 글

boj 1253 좋다  (0) 2021.10.21
boj 9024 두 수의 합  (0) 2021.10.21
boj 2559 수열  (0) 2021.02.12
boj 1806 부분합  (0) 2021.01.22
boj 2003 수들의 합 2  (0) 2021.01.22

www.acmicpc.net/problem/14923

 

14923번: 미로 탈출

홍익이는 사악한 마법사의 꾐에 속아 N x M 미로 (Hx, Hy) 위치에 떨어졌다. 다행히도 홍익이는 마법사가 만든 미로의 탈출 위치(Ex, Ey)를 알고 있다. 하지만 미로에는 곳곳에 마법사가 설치한 벽이

www.acmicpc.net

(hx, hy)에서 출발하여 (ex, ey)까지 갈 수 있는 최단거리를 출력합니다.

맵에는 벽이 있으며 벽을 1개까지 부술 수 있습니다.

 

www.acmicpc.net/problem/2206

 

2206번: 벽 부수고 이동하기

N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로

www.acmicpc.net

이 문제와 같은 풀이방식입니다.

이 문제와 다른점은 출발점과 도착점이 고정이 아니라는 점입니다.

 

visit[x][y][cnt] : (x, y)에 벽을 부수고 방문한 경우와 안부수고 방문한 경우를 나눠줍니다.

 

탈출이 가능하면 거리를 출력, 불가능하면 -1을 출력합니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Deque<int[]> dq = new ArrayDeque<>();
    static int list[][] = new int[1001][1001];
    static boolean visit[][][] = new boolean[1001][1001][2];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int N, M, ex, ey;
 
    static void bfs() {
        for (int t = 1;; t++) {
            int size = dq.size();
            while (size-- > 0) {
                int x = dq.peek()[0];
                int y = dq.peek()[1];
                int cnt = dq.poll()[2];
 
                for (int i = 0; i < 4; i++) {
                    int nx = x + direct[i][0];
                    int ny = y + direct[i][1];
 
                    if (nx < 1 || ny < 1 || nx > N || ny > M)
                        continue;
                    if (list[nx][ny] == 1) {
                        if (cnt > 0 || visit[nx][ny][1])
                            continue;
 
                        dq.add(new int[] { nx, ny, 1 });
                        visit[nx][ny][1= true;
                    } else {
                        if (visit[nx][ny][cnt])
                            continue;
 
                        dq.add(new int[] { nx, ny, cnt });
                        visit[nx][ny][cnt] = true;
 
                        if (nx == ex && ny == ey) {
                            System.out.println(t);
                            return;
                        }
                    }
                }
            }
 
            if (dq.isEmpty()) {
                System.out.println(-1);
                return;
            }
        }
    }
 
    static void input() throws Exception {
        int x, y;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        x = Integer.parseInt(st.nextToken());
        y = Integer.parseInt(st.nextToken());
        dq.add(new int[] { x, y, 0 });
        visit[x][y][0= true;
 
        st = new StringTokenizer(br.readLine());
        x = Integer.parseInt(st.nextToken());
        y = Integer.parseInt(st.nextToken());
        ex = x;
        ey = y;
 
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= M; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        bfs();
    }
}
cs

'algorithm > bfs' 카테고리의 다른 글

boj 17471 게리맨더링  (0) 2021.04.16
boj 2573 빙산  (0) 2021.04.05
boj 17836 공주님을 구해라!  (0) 2021.03.26
boj 9205 맥주 마시면서 걸어가기  (0) 2021.03.25
boj 1600 말이 되고픈 원숭이  (0) 2021.03.24

www.acmicpc.net/problem/1520

 

1520번: 내리막 길

첫째 줄에는 지도의 세로의 크기 M과 가로의 크기 N이 빈칸을 사이에 두고 주어진다. 이어 다음 M개 줄에 걸쳐 한 줄에 N개씩 위에서부터 차례로 각 지점의 높이가 빈 칸을 사이에 두고 주어진다.

www.acmicpc.net

emoney96.tistory.com/189

 

boj 1937 욕심쟁이 판다

www.acmicpc.net/problem/1937 1937번: 욕심쟁이 판다 n*n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중

emoney96.tistory.com

이 문제와 비슷한 풀이입니다.

dfs + dp를 사용하며

위의 문제는 칸의 수를 세어주었지만 이 문제는 (0, 0)에서 (N - 1, M - 1)까지 도달할 수 있는 경우의 수를 세어주는 문제입니다.

 

현재 칸보다 높이가 더 낮은 지점으로만 이동합니다.

(N - 1, M - 1)에 도달하면 1을 리턴하고 이미 방문한 좌표에는 해당 좌표의 dp[x][y]를 리턴해줍니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[][] = new int[500][500];
    static int dp[][] = new int[500][500];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int N, M;
 
    static int func(int x, int y) {
        if (x == N - 1 && y == M - 1)
            return 1;
        if (dp[x][y] != -1)
            return dp[x][y];
        dp[x][y] = 0;
 
        for (int i = 0; i < 4; i++) {
            int nx = x + direct[i][0];
            int ny = y + direct[i][1];
 
            if (nx < 0 || ny < 0 || nx >= N || ny >= M)
                continue;
            if (list[x][y] <= list[nx][ny])
                continue;
 
            dp[x][y] += func(nx, ny);
        }
        
        return dp[x][y];
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        for (int i = 0; i < N; i++) {
            Arrays.fill(dp[i], -1);
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        System.out.println(func(00));
    }
}
cs

'algorithm > dp' 카테고리의 다른 글

boj 10800 컬러볼  (0) 2021.04.09
boj 12869 뮤탈리스크  (0) 2021.04.04
boj 1937 욕심쟁이 판다  (0) 2021.03.28
boj 2201 이친수 찾기  (2) 2021.03.24
boj 2228 구간 나누기  (0) 2021.03.21

www.acmicpc.net/problem/1937

 

1937번: 욕심쟁이 판다

n*n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에서

www.acmicpc.net

판다는 4방향으로 다닐 수 있지만 대나무의 양이 현재보다 더 많은 곳으로 가야합니다.

완전 탐색을 하면 답을 찾을 수는 있지만 N의 범위가 500까지이므로 시간초과가 날 것입니다.

 

따라서 이 문제는 dfs + dp 문제입니다.

이미 팬더가 지나간 길에 대해서 다시 탐색할 필요가 없으므로 dp를 사용합니다.

dp[x][y] : (x, y)를 시작점으로 판다가 최대한 살 수 있는 일수

 

dfs에 dp가 추가된 간단한 문제였습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[][] = new int[501][501];
    static int dp[][] = new int[501][501];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int N, ans;
 
    static int dfs(int x, int y) {
        if (dp[x][y] != -1)
            return dp[x][y];
        dp[x][y] = 1;
 
        for (int i = 0; i < 4; i++) {
            int nx = x + direct[i][0];
            int ny = y + direct[i][1];
 
            if (nx < 0 || ny < 0 || nx >= N || ny >= N)
                continue;
            if (list[x][y] >= list[nx][ny])
                continue;
 
            dp[x][y] = Math.max(dp[x][y], dfs(nx, ny) + 1);
        }
 
        ans = Math.max(ans, dp[x][y]);
        return dp[x][y];
    }
 
    static void func() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (dp[i][j] != -1)
                    continue;
                dfs(i, j);
            }
        }
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        for (int i = 0; i < N; i++) {
            Arrays.fill(dp[i], -1);
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
            }
        }
 
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > dp' 카테고리의 다른 글

boj 12869 뮤탈리스크  (0) 2021.04.04
boj 1520 내리막 길  (0) 2021.03.28
boj 2201 이친수 찾기  (2) 2021.03.24
boj 2228 구간 나누기  (0) 2021.03.21
boj 1695 팰린드롬 만들기  (0) 2021.03.20

2021년에 처음으로 참여한 알고리즘 대회

 

싸피에서 어떤 교육생분이 홍보를 해주셔서 참여를 하게되었다.

 

플랫폼은 구름에서 했고, 나는 다행히도 2019, 2020 부산 코딩경진대회를 참여했을 때 구름에서 했기 때문에 적응에는 문제가 되지 않았다.

 

그렇게 3월20일 1차 코테, 6문제가 나왔다.

dp가 3문제, 정렬 1문제, bfs 1문제, 구현 1문제 이렇게 나왔던것 같다.

 

중간에 "제출이 실패하였습니다."라는 알림이 계속 뜨는바람에 멘탈이 나가버려서 문제에 집중도 안됐었고 그때문인지 20~30분 가량의 시간을 소비했던것 같다.. 아무튼 1시간 40분만에 올솔하고 나와버렸다..

 

근데 올솔을 했지만 확신은 없었던게 시험 난이도가 너무 쉬웠었고, 올솔 하신분이 엄청 많다고 생각했기 때문이다..

(다른 후기글을 봐도 1시간반 안에 다들 올솔했다고 하더라..)

 

하지만 합격해버렸다 ㅎㅎ

사실 목표가 2차 진출이었기에 나름 만족을 하였다.

 

그리고 어제, 2차 대회를 진행하였다.

 

문제는 4문제가 나왔다.

2차 대회라서 그런지 시험 도중 캠과 화면을 보여줘야 했지만 지속적으로 오류가 뜨는바람에 브라우저가 인식을 못하더라.... 덕분에 10분은 날려먹고 시작한듯 ㅠㅠ

 

1번은 그냥 구현으로 했던것 같고,

 

2번은 MST를 구하면 되는문제, 마침 싸피 커리큘럼에 MST가 있었어서 충분히 복습할 시간이 최근에 있어서 쉽게 해결했다.

 

3번은 lca문제가 나왔다.

맨 처음에 각 노드의 깊이를 dfs로 구현했다가 스택오버플로우가 뜬다는 것을 알게되었고 bfs로 급히 수정하였다. 하지만 몇몇 테케를 실험하는 도중에 코드를 살짝 바꿔놨었는데 그걸 다시 돌려놓는다는 생각을 못했었고, 거기서 많은 시간을 날리게 되었다.... 뒤늦게 찾고 AC를 받았다.

 

4번은 문자열에서 문자열을 찾는 문제가 나왔다.

싸피에서 KMP를 배웠기에 일단 그걸로 구현을 해봤지만 AC를 받지 못했다. 결과가 뜨는 시간을 보니 무조건 시간초과인것 같았다.. 분명 내가 모르는 알고리즘을 써야하는 문제라는 것을 깨닫고 결국 못풀었다 ㅠㅠ

(끝나고 나서 아호코라식 이라는 알고리즘을 쓰는 문제라고 하더라.. 나는 처음듣는 알고리즘이었다 ㅋㅋㅋㅋㅋㅋㅋ)

 

2차대회는 2솔을 목표로 두고 했지만 3솔을 해서 나름 만족이다.

하지만 3번을 하는 중에 삽질을 디게 많이해서 찝찝하다고나 할까...?

다음번엔 이런 실수를 줄여야겠다는 생각이 든다..

하지만 1차 때 "제출이 실패하였습니다" 라는 알림과 2차 때 캠 관련 문제, 채점데이터 문제 등 많은 이슈가 있어서 개인적으로 아쉬움이 남는 대회였다.. 이런 이슈때문에 아마 멘탈적인 부분도 비중이 있지 않았을까 라는 생각이 든다.

 

+ 와 2차대회 끝나고 고생했다고 치킨 기프티콘까지 주시네... ㄷㄷ 감사합니다 ㅎㅎ

 

+ 나는 3번문제 AC를 받은 상황이었어서 몰랐지만 3, 4번 문제 채점데이터에 문제가 있다는 연락을 받았고

확인한 내용을 4/2에 알려주겠다고 한다. 3번은 맞췄으니 아마 문제가 없지않을까 생각하지만 4번은 모르겠다..

kmp로 짠 소스에 최악의 경우인 테케를 넣어보니 시간초과겠구나 싶어서 별 기대는 하지않는다..

'잡담' 카테고리의 다른 글

8월 2주차 결산  (0) 2021.08.15
8월 1주차 결산  (0) 2021.08.08
7월 5주차 결산  (2) 2021.08.01
solved.ac에 잔디가 생겼어요!  (0) 2021.07.27
스코페 2차 결과  (0) 2021.04.02

www.acmicpc.net/problem/17836

 

17836번: 공주님을 구해라!

용사는 마왕이 숨겨놓은 공주님을 구하기 위해 (N, M) 크기의 성 입구 (1,1)으로 들어왔다. 마왕은 용사가 공주를 찾지 못하도록 성의 여러 군데 마법 벽을 세워놓았다. 용사는 현재의 가지고 있는

www.acmicpc.net

시작점 : (1, 1)

도착점 : (N, M)

제한 시간 : T

무기가 없으면 벽을 지나갈 수 없지만 무기가 있으면 모든 벽을 부수고 지나갈 수 있습니다.


visit[x][y][chk] : x, y에 도달했을 때 무기를 가진 상태로 방문했는지 여부

 

1. 다음 칸이 무기가 있는 칸일 경우(list[nx][ny] = 2)

- 무기를 획득하였으므로 chk=true인 값을 큐에 넣어줍니다.

2. 다음 칸이 벽이 아니고 방문하지 않았을 경우

- 평상시 bfs처럼 다음 정점을 큐에 넣고 방문체크합니다.

3. 다음 칸이 벽이고 무기를 가진 상태인 경우

- 무기를 갖고있으면 어디든 지나갈 수 있으므로 2번과 같은 로직을 수행합니다.

 

도착지점인 (N, M)의 값은 0이므로 2, 3번에서 (N, M)에 도달하였으면 현재 시간을 출력합니다.

만약 T시간 동안 (N, M)에 도달하지 못하면 Fail을 출력합니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <queue>
using namespace std;
 
typedef struct Point {
    int x;
    int y;
    bool chk;
};
 
queue<Point> q;
bool visit[101][101][2];
int list[101][101];
int direct[4][2= { {0,1},{1,0},{0,-1},{-1,0} };
int N, M, T;
 
void bfs() {
    q.push({ 1,1,false });
    visit[1][1][0= true;
    for (int t = 1; t <= T; t++) {
        int qsize = q.size();
        while (qsize--) {
            int x = q.front().x;
            int y = q.front().y;
            bool chk = q.front().chk;
            q.pop();
 
            for (int i = 0; i < 4; i++) {
                int nx = x + direct[i][0];
                int ny = y + direct[i][1];
 
                if (nx < 1 || ny < 1 || nx > N || ny > M) continue;
                if (list[nx][ny] == 2 && !visit[nx][ny][1]) {
                    q.push({ nx,ny,true });
                    visit[nx][ny][1= true;
                }
                else if (list[nx][ny] == 0 && !visit[nx][ny][chk]) {
                    q.push({ nx,ny,chk });
                    visit[nx][ny][chk] = true;
                    if (nx == N && ny == M) {
                        cout << t << '\n';
                        return;
                    }
                }
                else if (list[nx][ny] == 1 && chk && !visit[nx][ny][chk]) {
                    q.push({ nx,ny,chk });
                    visit[nx][ny][chk] = true;
                    if (nx == N && ny == M) {
                        cout << t << '\n';
                        return;
                    }
                }
            }
        }
    }
 
    cout << "Fail\n";
}
 
void input() {
    cin >> N >> M >> T;
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            cin >> list[i][j];
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    bfs();
 
    return 0;
}
cs

'algorithm > bfs' 카테고리의 다른 글

boj 2573 빙산  (0) 2021.04.05
boj 14923 미로 탈출  (0) 2021.03.29
boj 9205 맥주 마시면서 걸어가기  (0) 2021.03.25
boj 1600 말이 되고픈 원숭이  (0) 2021.03.24
boj 2589 보물섬  (0) 2021.03.16

www.acmicpc.net/problem/9205

 

9205번: 맥주 마시면서 걸어가기

송도에 사는 상근이와 친구들은 송도에서 열리는 펜타포트 락 페스티벌에 가려고 한다. 올해는 맥주를 마시면서 걸어가기로 했다. 출발은 상근이네 집에서 하고, 맥주 한 박스를 들고 출발한다.

www.acmicpc.net

1번 정점 : 시작점

2번 ~ N + 1번 정점 : 편의점

N + 2번 정점 : 도착점

 

bfs와 플로이드 와샬 두 가지 방법을 이용할 수 있습니다.

 

먼저 bfs 풀이로는 N^2으로 각 정점들 사이의 거리가 1000이하인 간선만 그래프화 시켜줍니다.

그 다음 1번정점으로 시작하여 bfs로 인접한 모든 정점을 방문한 후에 N + 2번 정점을 방문하였는지 확인합니다.

N + 2번 정점을 방문 하였으면 happy, 방문 안했으면 sad를 출력합니다.

 

 

플로이드 풀이로는 N^2으로 각 정점들 사이의 거리가 1000이하면 dis[i][j] = true를 하여 간선체크를 해줍니다.

그 다음 플로이드를 사용하는데 i ~ k번을 지나갈 수 있고, k ~ j번을 지나갈 수 있으면 i ~ j번을 지나갈 수 있습니다.

따라서 dis[i][k] && dis[k][j]이면 dis[i][j] = true를 해줍니다.

dis[1][N+2] = true면 happy, false면 sad를 출력합니다.

 

bfs
플로이드 와샬

 

실행 시간은 bfs쪽이 좀 더 빨랐습니다.

 

 

[bfs]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static ArrayList<Integer> graph[] = new ArrayList[103];
    static boolean visit[] = new boolean[103];
    static int list[][] = new int[103][2];
    static int N;
 
    static void bfs() {
        Deque<Integer> dq = new ArrayDeque<>();
        dq.add(1);
        visit[1= true;
        while (!dq.isEmpty()) {
            int x = dq.poll();
 
            for (int i = 0; i < graph[x].size(); i++) {
                int next = graph[x].get(i);
 
                if (visit[next])
                    continue;
 
                dq.add(next);
                visit[next] = true;
            }
        }
 
        if (visit[N + 2])
            sb.append("happy\n");
        else
            sb.append("sad\n");
    }
 
    static boolean getDis(int a[], int b[]) {
        return (Math.abs(a[0- b[0]) + Math.abs(a[1- b[1])) <= 1000 ? true : false;
    }
 
    static void func() {
        for (int i = 1; i <= N + 1; i++) {
            for (int j = i + 1; j <= N + 2; j++) {
                if (getDis(list[i], list[j])) {
                    graph[i].add(j);
                    graph[j].add(i);
                }
            }
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        for (int i = 1; i <= N + 2; i++) {
            st = new StringTokenizer(br.readLine());
            list[i][0= Integer.parseInt(st.nextToken());
            list[i][1= Integer.parseInt(st.nextToken());
        }
    }
 
    static void init() {
        Arrays.fill(visit, false);
        for (int i = 1; i <= N + 2; i++) {
            graph[i] = new ArrayList<>();
        }
    }
 
    public static void main(String[] args) throws Exception {
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            input();
            init();
            func();
            bfs();
        }
        System.out.println(sb.toString());
    }
}
cs

 

 

[플로이드 와샬]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static int list[][] = new int[103][2];
    static boolean dis[][] = new boolean[103][103];
    static int N;
 
    static int getDis(int x, int y, int tx, int ty) {
        return Math.abs(x - tx) + Math.abs(y - ty);
    }
 
    static void func() {
        for (int i = 1; i <= N + 1; i++) {
            for (int j = i + 1; j <= N + 2; j++) {
                if (getDis(list[i][0], list[i][1], list[j][0], list[j][1]) <= 1000) {
                    dis[i][j] = true;
                    dis[j][i] = true;
                }
            }
        }
 
        for (int k = 1; k <= N + 2; k++) {
            for (int i = 1; i <= N + 2; i++) {
                for (int j = 1; j <= N + 2; j++) {
                    if (dis[i][k] && dis[k][j])
                        dis[i][j] = true;
                }
            }
        }
 
        if (dis[1][N + 2])
            sb.append("happy\n");
        else
            sb.append("sad\n");
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        for (int i = 1; i <= N + 2; i++) {
            st = new StringTokenizer(br.readLine());
            list[i][0= Integer.parseInt(st.nextToken());
            list[i][1= Integer.parseInt(st.nextToken());
        }
    }
 
    static void init() {
        for (int i = 1; i <= N + 2; i++)
            Arrays.fill(dis[i], false);
    }
 
    public static void main(String[] args) throws Exception {
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        for (int t = 1; t <= tc; t++) {
            input();
            func();
            init();
        }
 
        System.out.println(sb.toString());
    }
}
cs

'algorithm > bfs' 카테고리의 다른 글

boj 14923 미로 탈출  (0) 2021.03.29
boj 17836 공주님을 구해라!  (0) 2021.03.26
boj 1600 말이 되고픈 원숭이  (0) 2021.03.24
boj 2589 보물섬  (0) 2021.03.16
boj 11559 Puyo Puyo  (0) 2021.02.26

www.acmicpc.net/problem/14938

 

14938번: 서강그라운드

예은이는 요즘 가장 인기가 있는 게임 서강그라운드를 즐기고 있다. 서강그라운드는 여러 지역중 하나의 지역에 낙하산을 타고 낙하하여, 그 지역에 떨어져 있는 아이템들을 이용해 서바이벌을

www.acmicpc.net

플로이드 와샬 알고리즘을 이용하여 각 정점에서부터의 최단거리를 모두 구해줍니다.

그리고 1 ~ N정점을 시작점으로 다른 정점과의 거리가 M 이하인 경우만 아이템 수를 더해줍니다.

다 더했으면 최댓값을 갱신해줍니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <algorithm>
#define INF 1000000000
using namespace std;
 
int dis[101][101], list[101];
int N, M, R;
 
void solve() {
    int ans = 0;
    for (int i = 1; i <= N; i++) {
        int sum = 0;
        for (int j = 1; j <= N; j++) {
            if (dis[i][j] > M) continue;
 
            sum += list[j];
        }
        ans = max(ans, sum);
    }
 
    cout << ans << '\n';
}
 
void func() {
    for (int k = 1; k <= N; k++) {
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= N; j++){
                dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
            }
        }
    }
}
 
void init() {
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            if (i == j) dis[i][j] = 0;
            else dis[i][j] = INF;
        }
    }
}
 
void input() {
    int u, v, w;
    cin >> N >> M >> R;
    init();
    for (int i = 1; i <= N; i++) {
        cin >> list[i];
    }
    while (R--) {
        cin >> u >> v >> w;
        dis[u][v] = w;
        dis[v][u] = w;
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
    solve();
 
    return 0;
}
cs

'algorithm > Floyd' 카테고리의 다른 글

boj 2273 줄 서기  (0) 2021.04.16

www.acmicpc.net/problem/1600

 

1600번: 말이 되고픈 원숭이

첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있

www.acmicpc.net

bfs 탐색인데 4방탐색에 위 사진과 같은 이동방식이 추가되었습니다.

위 사진처럼 말과 같이 움직일 수 있는 횟수가 K로 정해져있습니다. (0 <= K <= 30)

 

그러므로 방문체크는 3차원 배열로 해줍니다.

visit[x][y][k] : 말과 같이 움직인 횟수가 k번인 상태로 (x, y)에 도착한 경우

 

저는 방향탐색에 대한 좌표이동을 인덱스를 기준으로 나누었습니다.

1. 0 ~ 3번 인덱스 : 4방탐색

2. 4 ~ 11번 인덱스 : 말처럼 이동

4방탐색의 경우 k의 변화 없이 이동시켜줍니다.

말처럼 이동하는 경우 K미만으로 움직였을 경우에만 움직여줍니다.

 

(N - 1, M - 1)에 도달하였으면 시간을 출력합니다.

 

 

[C++]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <queue>
using namespace std;
 
queue<pair<pair<intint>pair<intint> > > q;
bool visit[200][200][31];
int map[200][200];
int x_direct[] = { 0,1,0,-1,-2,-1,1,2,2,1,-1,-2 }, y_direct[] = { 1,0,-1,0,1,2,2,1,-1,-2,-2,-1 };
int K, H, W, ans = -1;
 
void bfs() {
    while (!q.empty()) {
        int x = q.front().first.first;
        int y = q.front().first.second;
        int cnt = q.front().second.first;
        int horse = q.front().second.second;
        q.pop();
 
        if (x == H - 1 && y == W - 1) {
            ans = cnt;
            return;
        }
 
        for (int i = 0; i < 12; i++) {
            int xx = x + x_direct[i];
            int yy = y + y_direct[i];
 
            if (xx < 0 || yy < 0 || xx >= H || yy >= W) continue;
            if (map[xx][yy] == 1continue;
 
            if (x_direct[i] == 2 || x_direct[i] == -2 || y_direct[i] == 2 || y_direct[i] == -2) {
                if (visit[xx][yy][horse + 1|| horse == K) continue;
                q.push(make_pair(make_pair(xx, yy), make_pair(cnt + 1, horse + 1)));
                visit[xx][yy][horse + 1= true;
            }
            else {
                if (visit[xx][yy][horse]) continue;
                q.push(make_pair(make_pair(xx, yy), make_pair(cnt + 1, horse)));
                visit[xx][yy][horse] = true;
            }
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    cin >> K >> W >> H;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            cin >> map[i][j];
        }
    }
 
    q.push(make_pair(make_pair(00), make_pair(00)));
    visit[0][0][0= true;
    bfs();
 
    cout << ans << '\n';
 
    return 0;
}
cs

 

 

[Java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[][] = new int[201][201];
    static boolean visit[][][] = new boolean[201][201][31];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 }, { 12 }, { 1-2 }, { -12 }, { -1-2 },
            { 21 }, { 2-1 }, { -21 }, { -2-1 } };
    static int N, M, K;
 
    static void bfs() {
        Deque<int[]> dq = new ArrayDeque<>();
        dq.add(new int[] { 000 });
        visit[0][0][0= true;
        for (int t = 1;; t++) {
            int size = dq.size();
            while (size-- > 0) {
                int x = dq.peek()[0];
                int y = dq.peek()[1];
                int cnt = dq.poll()[2];
 
                if (x == N - 1 && y == M - 1) {
                    System.out.println(t - 1);
                    return;
                }
 
                for (int i = 0; i < 12; i++) {
                    int nx = x + direct[i][0];
                    int ny = y + direct[i][1];
 
                    if (nx < 0 || ny < 0 || nx >= N || ny >= M)
                        continue;
                    if (list[nx][ny] == 1)
                        continue;
 
                    if (i < 4) {
                        if (visit[nx][ny][cnt])
                            continue;
                        dq.add(new int[] { nx, ny, cnt });
                        visit[nx][ny][cnt] = true;
                    } else {
                        if (cnt + 1 > K || visit[nx][ny][cnt + 1])
                            continue;
                        dq.add(new int[] { nx, ny, cnt + 1 });
                        visit[nx][ny][cnt + 1= true;
                    }
                }
            }
 
            if (dq.isEmpty()) {
                System.out.println(-1);
                return;
            }
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        K = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        N = Integer.parseInt(st.nextToken());
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        bfs();
    }
}
cs

'algorithm > bfs' 카테고리의 다른 글

boj 17836 공주님을 구해라!  (0) 2021.03.26
boj 9205 맥주 마시면서 걸어가기  (0) 2021.03.25
boj 2589 보물섬  (0) 2021.03.16
boj 11559 Puyo Puyo  (0) 2021.02.26
boj 15653 구슬 탈출 4  (0) 2021.02.22

www.acmicpc.net/problem/2201

 

2201번: 이친수 찾기

0과 1로만 이루어진 수를 이진수라 한다. 이러한 이진수 들 특별한 성질을 갖는 것들이 있는데, 이들을 이친수(pinary number)라 한다. 이친수는 다음의 성질을 만족한다. 이친수는 0으로 시작하지 않

www.acmicpc.net

 

dp[length] : 길이가 length인 이친수의 시작 번호

 

1. 이친수는 0으로 시작하지 않는다.

2. 이친수에서는 1이 두 번 연속으로 나타나지 않는다. 즉, 11은 이친수가 아니다.

위 조건을 고려하여 길이당 이친수의 갯수는 피보나치 수열로 구할 수 있습니다.

 

저는 이를 이용하여 dp에 각 길이당 시작하는 번호를 담아놓습니다.

dp[1] = 1, dp[2] = 2, dp[3]= 3, dp[4] = 5, dp[5]=8, dp[6] = 13, ... 이런식으로 되고,

 

그리고 입력받은 N의 길이를 구합니다.

길이가 i일 때의 시작번호와 비교를 하여 dp[i] > N이면 length는 i - 1입니다.

 

그리고 length만큼 반복문을 돌려주면서 두 가지의 경우를 확인합니다.

1. dp[length] <= N이면 (번호 N이 length의 시작점보다 뒤에 있으면)

 => 1을 출력하고 N을 N의 시작번호만큼 빼줍니다.

 

2. dp[length] > N이면 (번호 N이 length의 시작점보다 앞에 있으면)

 => 0을 출력합니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
using namespace std;
typedef long long ll;
 
ll dp[91], N;
 
void init() {
    dp[1= 1;
    dp[2= 2;
    for (int i = 3; i <= 90; i++) {
        dp[i] = dp[i - 1+ dp[i - 2];
    }
}
 
void solve() {
    int length = 0;
    for (int i = 1; i <= 90; i++) {
        if (dp[i] > N) {
            length = i - 1;
            break;
        }
    }
 
    while (length) {
        if (dp[length] <= N) {
            cout << 1;
            N -= dp[length];
        }
        else {
            cout << 0;
        }
        length--;
    }
    cout << '\n';
}
 
void input() {
    cin >> N;
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    init();
    input();
    solve();
 
    return 0;
}
cs

'algorithm > dp' 카테고리의 다른 글

boj 1520 내리막 길  (0) 2021.03.28
boj 1937 욕심쟁이 판다  (0) 2021.03.28
boj 2228 구간 나누기  (0) 2021.03.21
boj 1695 팰린드롬 만들기  (0) 2021.03.20
boj 9177 단어 섞기  (0) 2021.03.19

www.acmicpc.net/problem/4485

 

4485번: 녹색 옷 입은 애가 젤다지?

젤다의 전설 게임에서 화폐의 단위는 루피(rupee)다. 그런데 간혹 '도둑루피'라 불리는 검정색 루피도 존재하는데, 이걸 획득하면 오히려 소지한 루피가 감소하게 된다! 젤다의 전설 시리즈의 주

www.acmicpc.net

 

다익스트라 기초에 2차원좌표가 추가되었습니다.

출발지점는 (0, 0)이고 도착지점은 (N - 1, N - 1)입니다.

그럼 (0, 0)에서 출발하여 각 칸까지의 최소비용을 구해주시면 됩니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <queue>
#include <cstring>
#define INF 1000000000
using namespace std;
 
typedef struct Point {
    int x;
    int y;
    int dis;
}Point;
 
int list[125][125], d[125][125];
int direct[4][2= { {0,1},{1,0},{0,-1},{-1,0} };
int N;
 
struct compare {
    bool operator()(Point a, Point b) {
        return a.dis > b.dis;
    }
};
 
void dijkstra() {
    priority_queue<Point, vector<Point>, compare> q;
    q.push({ 0,0,list[0][0] });
    d[0][0= list[0][0];
    while (!q.empty()) {
        int x = q.top().x;
        int y = q.top().y;
        int dis = q.top().dis;
        q.pop();
 
        if (d[x][y] < dis) continue;
 
        for (int i = 0; i < 4; i++) {
            int nx = x + direct[i][0];
            int ny = y + direct[i][1];
 
            if (nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
            int nextdis = dis + list[nx][ny];
            if (d[nx][ny] > nextdis) {
                d[nx][ny] = nextdis;
                q.push({ nx, ny, nextdis });
            }
        }
    }
}
 
void input() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> list[i][j];
        }
    }
}
 
void init() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            d[i][j] = INF;
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    for (int t = 1; ; t++) {
        input();
        if (!N) return 0;
        init();
        dijkstra();
        cout << "Problem " << t << ": " << d[N - 1][N - 1<< '\n';
    }
}
cs

'algorithm > dijkstra' 카테고리의 다른 글

boj 18352 특정 거리의 도시 찾기  (0) 2021.03.22
boj 14496 그대, 그머가 되어  (0) 2021.03.22

+ Recent posts