www.acmicpc.net/problem/1931

 

1931번: 회의실 배정

(1,4), (5,7), (8,11), (12,14) 를 이용할 수 있다.

www.acmicpc.net

회의실이 1개이고, 이를 사용할 수 있는 회의의 최대 갯수를 출력하는 문제입니다.

저는 회의 종료시간 기준으로 정렬한 후 그리디로 해결하였습니다.

 

회의 종료시간을 유지하면서 다음 회의부터 N까지 순회를 합니다.

현재 회의 종료시간이 다음 회의의 시작시간보다 작거나 같을때마다 종료시간을 갱신하고, ans를 1 늘려줍니다.

N번까지 순회 이후 ans를 출력합니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[][];
    static int N, ans = 1;
 
    static void func() {
        int e = list[0][1];
        for (int i = 1; i < N; i++) {
            if (e <= list[i][0]) {
                e = list[i][1];
                ans++;
            }
        }
 
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N][2];
 
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i][0= Integer.parseInt(st.nextToken());
            list[i][1= Integer.parseInt(st.nextToken());
        }
        Arrays.sort(list, new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                if (a[1== b[1]) {
                    if (a[0< b[0])
                        return -1;
                    else
                        return 1;
                } else {
                    if (a[1< b[1])
                        return -1;
                    else
                        return 1;
                }
            }
        });
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 8980 택배  (0) 2021.02.16
boj 11000 강의실 배정  (0) 2021.02.16
boj 2839 설탕 배달  (0) 2021.02.16
boj 11399 ATM  (0) 2021.01.29
boj 1339 단어 수학  (0) 2021.01.22

www.acmicpc.net/problem/2839

 

2839번: 설탕 배달

상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그

www.acmicpc.net

설탕 Nkg을 3kg 봉지와 5kg 봉지로 담는 그리디 문제입니다.

봉지가 담을 수 있는 무게가 3, 5 kg으로 한정되어있으니 설탕의 무게는 (3의배수 + 5의배수) kg이 됩니다.

 

우선 5kg이 가장 크기때문에 N이 5로 나누어떨어지면 모든 설탕을 5kg에 담으면 됩니다.

그렇지 않으면 3kg씩 빼주면서 다시 N이 5로 나누어떨어지는지 확인하는 방식으로 구현하였습니다.

 

만약 위의 과정에서 N이 5보다 작고 3의배수가 아니면 -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
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 int N;
 
    static void func() {
        int ans = 0;
        while (true) {
            if (N % 5 == 0) {
                ans += (N / 5);
                N = 0;
            } else {
                ans++;
                N -= 3;
            }
 
            if (N == 0)
                break;
            
            if (N < 5 && N % 3 != 0) {
                ans = -1;
                break;
            }
        }
 
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 8980 택배  (0) 2021.02.16
boj 11000 강의실 배정  (0) 2021.02.16
boj 1931 회의실 배정  (0) 2021.02.16
boj 11399 ATM  (0) 2021.01.29
boj 1339 단어 수학  (0) 2021.01.22

www.acmicpc.net/problem/3040

 

3040번: 백설 공주와 일곱 난쟁이

매일 매일 일곱 난쟁이는 광산으로 일을 하러 간다. 난쟁이가 일을 하는 동안 백설공주는 그들을 위해 저녁 식사를 준비한다. 백설공주는 의자 일곱개, 접시 일곱개, 나이프 일곱개를 준비한다.

www.acmicpc.net

부르트포스 방식으로 9개 중 7개를 뽑는 과정에서 7개의 합이 100이 되면 뽑은 수들을 출력하면 되는 문제입니다.

9개중 7개를 뽑는다고 명시가 되어있으니 조합으로 해결해야하고, 7개를 뽑았을 때 합이 100인 수들을 출력하면 됩니다.

7개를 뽑았으나 합이 100이 아닌경우에 그냥 리턴을 시켜주시면 되고, 재귀를 돌릴때 다음 매개변수 sum이 100보다 크면 continue를 해서 시간단축을 하였습니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
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 ArrayList<Integer> ans = new ArrayList<>();
    static int list[] = new int[9];
 
    static void func(int idx, int cnt, int sum) {
        if (cnt == 7) {
            if (sum != 100)
                return;
 
            for (int i = 0; i < 7; i++) {
                sb.append(ans.get(i) + "\n");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = idx; i < 9; i++) {
            if (sum + list[i] > 100)
                continue;
            
            ans.add(list[i]);
            func(i + 1, cnt + 1, sum + list[i]);
            ans.remove(cnt);
        }
    }
 
    static void input() throws Exception {
        for (int i = 0; i < 9; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(000);
        System.out.println(sb.toString());
    }
}
cs

www.acmicpc.net/problem/2961

 

2961번: 도영이가 만든 맛있는 음식

첫째 줄에 재료의 개수 N(1 ≤ N ≤ 10)이 주어진다. 다음 N개 줄에는 그 재료의 신맛과 쓴맛이 공백으로 구분되어 주어진다. 모든 재료를 사용해서 요리를 만들었을 때, 그 요리의 신맛과 쓴맛은

www.acmicpc.net

브루트포스 방식으로 모든 경우를 다 계산해주시면 됩니다.

N개 중에 뽑는 갯수가 정해져있지 않기때문에 조합이 아닌 부분집합으로 재료를 고를때마다 ans를 갱신해줍니다.

 

 

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
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 long list[][];
    static long ans = Long.MAX_VALUE;
    static int N;
 
    static void func(int idx, long a, long b) {
        if (idx > 0)
            ans = Math.min(ans, Math.abs(a - b));
        
        if (idx == N)
            return;
 
        for (int i = idx; i < N; i++) {
            func(i + 1, a * list[i][0], b + list[i][1]);
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new long[N][2];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i][0= Long.parseLong(st.nextToken());
            list[i][1= Long.parseLong(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(010);
        System.out.println(ans);
    }
}
cs

 

www.acmicpc.net/problem/15480

 

15480번: LCA와 쿼리

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N-1개의 줄에는 트리 T의 간선 정보 u와 v가 주어지다. u와 v는 트리의 간선을 나타내는 두 정점이다. 다음 줄에는 쿼리의 개수 M(

www.acmicpc.net

먼저 트리의 구조가 주어지고 쿼리가 r u v 형식으로 주어집니다.

r u v는 루트가 r일 때 u와 v의 LCA를 출력해야합니다.

 

루트가 r일 때 u와 v의 LCA는

r, u의 lca노드의 depth

r, v의 lca노드의 depth

u, v의 lca노드의 depth

중 가장 큰 depth를 가진 노드가 정답이 됩니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static ArrayList<Integer> list[];
    static boolean visit[];
    static int parent[][] = new int[100001][21];
    static int depth[];
    static int N, M;
 
    static 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].get(i);
 
            if (visit[next])
                continue;
            parent[next][0= v;
            dfs(next, d + 1);
        }
    }
 
    static void func() {
        dfs(11);
        for (int j = 1; j < 21; j++) {
            for (int i = 1; i <= N; i++) {
                parent[i][j] = parent[parent[i][j - 1]][j - 1];
            }
        }
    }
 
    static int lca(int x, int y) {
        if (depth[x] > depth[y]) {
            int tmp = x;
            x = y;
            y = tmp;
        }
 
        for (int i = 20; i >= 0; i--) {
            if (depth[y] - depth[x] >= (1 << i)) {
                y = parent[y][i];
            }
        }
 
        if (x == y)
            return x;
 
        for (int i = 20; i >= 0; i--) {
            if (parent[x][i] != parent[y][i]) {
                x = parent[x][i];
                y = parent[y][i];
            }
        }
 
        return parent[x][0];
    }
 
    static void solve() throws Exception {
        StringBuffer sb = new StringBuffer();
        int r, u, v;
        st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        while (M-- > 0) {
            st = new StringTokenizer(br.readLine());
            r = Integer.parseInt(st.nextToken());
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
 
            int a = lca(r, u);
            int b = lca(r, v);
            int c = lca(u, v);
            int ans = depth[a] > depth[b] ? (depth[a] > depth[c] ? a : c) : (depth[b] > depth[c] ? b : c);
 
            sb.append(ans + "\n");
        }
 
        System.out.print(sb.toString());
    }
 
    static void input() throws Exception {
        int u, v;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        depth = new int[N + 1];
        visit = new boolean[N + 1];
        list = new ArrayList[N + 1];
        for (int i = 1; i <= N; i++)
            list[i] = new ArrayList<>();
 
        for (int i = 0; i < N - 1; i++) {
            st = new StringTokenizer(br.readLine());
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
 
            list[u].add(v);
            list[v].add(u);
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        solve();
    }
}
cs

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

boj 1626 두 번째로 작은 스패닝 트리  (0) 2021.04.02
boj 15481 그래프와 MST  (0) 2021.04.01
boj 11438 LCA 2  (0) 2021.02.11
boj 11437 LCA  (0) 2021.02.11
boj 13116 30번  (0) 2021.02.09

www.acmicpc.net/problem/16236

 

16236번: 아기 상어

N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가

www.acmicpc.net

상어가 지나갈 수 있는 경우는

1. 자신의 크기보다 작거나 같은 물고기가 있는 경우

2. 빈 칸

이렇게 두 가지이며, 상어는 자신보다 작은 물고기만 먹을 수 있습니다.

그리고 자신의 크기와 같은 수의 물고기를 먹으면 크기가 1 커집니다.

 

상어가 먹을 수 있는 물고기를 bfs로 찾고,

먹을 수 있는 물고기가 여러마리면 그 중 가장 가까운 물고기, 가장 위에 있는 물고기, 가장 왼쪽에 있는 물고기 순으로 먹습니다.

 

저는 bfs로 순회하며 먹을 수 있는 물고기를 ArrayList에 담았고 위의 조건 순으로 정렬하였습니다.

그럼 0번 인덱스에 있는 물고기를 먹으면 되고, 그 물고기까지의 거리를 ans에 더해주고, 그 위치에서 다시 시작합니다.

위의 과정을 물고기를 먹을 수 있을때까지 반복해줍니다.

 

 

[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
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
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
 
queue<pair<intint> > q;
int list[21][21];
bool visit[21][21];
int direct[4][2= { {0,1},{1,0},{0,-1},{-1,0} };
int N, ans;
 
bool cmp(pair<intint> a, pair<intint> b) {
    if (a.first < b.first) return true;
    else if (a.first == b.first) {
        if (a.second < b.second) return true;
        else return false;
    }
    else return false;
}
 
void bfs() {
    int ssize = 2;
    int eat = 0;
    while (1) {
        bool chk = false;
        vector<pair<intint> > v;
        for (int t = 1; ; t++) {
            int qsize = q.size();
            while (qsize--) {
                int x = q.front().first;
                int y = q.front().second;
                q.pop();
 
                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 (visit[nx][ny]) continue;
                    if (list[nx][ny] > ssize) continue;
 
                    if (list[nx][ny] && list[nx][ny] < ssize) {
                        v.push_back({ nx,ny });
                    }
                    q.push({ nx,ny });
                    visit[nx][ny] = true;
                }
            }
 
            if (!v.empty()) {
                ans += t;
                break;
            }
            if (q.empty()) {
                chk = true;
                break;
            }
        }
        if (chk) break;
 
        sort(v.begin(), v.end(), cmp);
        int x = v[0].first;
        int y = v[0].second;
        list[x][y] = 0;
        eat++;
        if (eat == ssize) {
            ssize++;
            eat = 0;
        }
        v.clear();
        memset(visit, falsesizeof(visit));
        while (!q.empty()) q.pop();
        q.push({ x,y });
        visit[x][y] = true;
    }
 
    cout << ans << '\n';
}
 
void input() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> list[i][j];
            if (list[i][j] == 9) {
                q.push({ i,j });
                visit[i][j] = true;
                list[i][j] = 0;
            }
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    bfs();
 
    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
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
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.StringTokenizer;
import java.io.BufferedReader;
 
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[21][21];
    static boolean visit[][] = new boolean[21][21];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int N, ans;
 
    static void bfs() {
        int size = 2;
        int eat = 0;
        while (true) {
            boolean chk = false;
            ArrayList<int[]> eatlist = new ArrayList<>();
            for (int t = 1;; t++) {
                int qsize = dq.size();
                while (qsize-- > 0) {
                    int x = dq.peek()[0];
                    int y = dq.poll()[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 (visit[nx][ny])
                            continue;
                        if (list[nx][ny] > size)
                            continue;
 
                        if (list[nx][ny] != 0 && list[nx][ny] < size) {
                            eatlist.add(new int[] { nx, ny });
                        }
                        dq.add(new int[] { nx, ny });
                        visit[nx][ny] = true;
                    }
                }
 
                if (!eatlist.isEmpty()) {
                    ans += t;
                    break;
                }
                if (dq.isEmpty()) {
                    chk = true;
                    break;
                }
            }
 
            if (chk)
                break;
 
            Collections.sort(eatlist, new Comparator<int[]>() {
                @Override
                public int compare(int[] a, int[] b) {
                    if (a[0== b[0])
                        return a[1- b[1];
                    else
                        return a[0- b[0];
                }
            });
 
            int x = eatlist.get(0)[0];
            int y = eatlist.get(0)[1];
            list[x][y] = 0;
            eat++;
            if (eat == size) {
                eat = 0;
                size++;
            }
 
            dq.clear();
            eatlist.clear();
            for (int i = 0; i < N; i++)
                Arrays.fill(visit[i], false);
            dq.add(new int[] { x, y });
            visit[x][y] = true;
        }
        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++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
                if (list[i][j] == 9) {
                    list[i][j] = 0;
                    dq.add(new int[] { i, j });
                    visit[i][j] = true;
                }
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        bfs();
    }
}
cs

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

boj 7576 토마토  (0) 2021.02.19
boj 17135 캐슬 디펜스  (0) 2021.02.17
boj 10026 적록색약  (0) 2021.02.13
boj 2206 벽 부수고 이동하기  (0) 2021.02.13
boj 14502 연구소  (0) 2021.02.12

www.acmicpc.net/problem/10026

 

10026번: 적록색약

적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다. 크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록)

www.acmicpc.net

적록색약이 아닌 사람이 봤을 때 구역의 갯수, 적록색약인 사람이 봤을 때 구역의 갯수를 순서대로 출력합니다.

적록색약이 아닌 사람 먼저 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
86
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static boolean visit[][];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static char list[][];
    static int N;
 
    static void bfs(int sx, int sy) {
        Queue<int[]> q = new LinkedList<>();
        q.add(new int[] { sx, sy });
        visit[sx][sy] = true;
        while (!q.isEmpty()) {
            int x = q.peek()[0];
            int y = q.poll()[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 (visit[nx][ny] || list[x][y] != list[nx][ny])
                    continue;
 
                q.add(new int[] { nx, ny });
                visit[nx][ny] = true;
            }
        }
    }
 
    static void func() {
        int ansFirst = 0;
        int ansSecond = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (visit[i][j])
                    continue;
                bfs(i, j);
                ansFirst++;
            }
        }
 
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                visit[i][j] = false;
                if (list[i][j] == 'G')
                    list[i][j] = 'R';
            }
        }
 
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (visit[i][j])
                    continue;
                bfs(i, j);
                ansSecond++;
            }
        }
 
        System.out.println(ansFirst + " " + ansSecond);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new char[N][N];
        visit = new boolean[N][N];
 
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = st.nextToken().toCharArray();
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 17135 캐슬 디펜스  (0) 2021.02.17
boj 16236 아기 상어  (0) 2021.02.14
boj 2206 벽 부수고 이동하기  (0) 2021.02.13
boj 14502 연구소  (0) 2021.02.12
boj 20304 비밀번호 제작  (0) 2021.02.08

www.acmicpc.net/problem/2206

 

2206번: 벽 부수고 이동하기

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

www.acmicpc.net

(0, 0) ~ (N - 1, M - 1)까지 bfs로 순회하는데 벽을 한 개 까지 부수고 이동할 수 있습니다.

저는 visit배열을 3차원배열로 선언하여 (x, y, broke) => 벽을 broke번 부수고 x, y에 방문한 경우를 체크하였습니다.

벽을 이미 부순 경우에는 다음 벽을 부술 수 없고, 벽을 부수지 않은 경우에만 다음 벽을 부술 수 있습니다.

(N - 1, M - 1)에 도달하면 cnt값을 출력, 큐가 비어있음에도 도달하지 못하면 -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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Queue<int[]> q = new LinkedList<>();
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static boolean visit[][][];
    static char list[][];
    static int N, M, ans = -1;
 
    static void bfs() {
        q.add(new int[] { 0010 });
        visit[0][0][0= true;
        while (!q.isEmpty()) {
            int x = q.peek()[0];
            int y = q.peek()[1];
            int cnt = q.peek()[2];
            int broke = q.poll()[3];
 
            if (x == N - 1 && y == M - 1) {
                ans = cnt;
                break;
            }
 
            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[nx][ny] == '1' && broke == 1)
                    continue;
 
                if (list[nx][ny] == '1') {
                    if (visit[nx][ny][1])
                        continue;
                    q.add(new int[] { nx, ny, cnt + 11 });
                    visit[nx][ny][1= true;
                } else {
                    if (visit[nx][ny][broke])
                        continue;
                    q.add(new int[] { nx, ny, cnt + 1, broke });
                    visit[nx][ny][broke] = true;
                }
            }
        }
 
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new char[N][];
        visit = new boolean[N][M][2];
 
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = st.nextToken().toCharArray();
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        bfs();
    }
}
cs

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

boj 16236 아기 상어  (0) 2021.02.14
boj 10026 적록색약  (0) 2021.02.13
boj 14502 연구소  (0) 2021.02.12
boj 20304 비밀번호 제작  (0) 2021.02.08
boj 2606 바이러스  (0) 2021.02.03

www.acmicpc.net/problem/14502

 

14502번: 연구소

인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크

www.acmicpc.net

연구소에 벽 3개를 설치하여 바이러스로부터 안전 영역의 크기를 최대로 해야합니다.

이 문제는 브루트포스 방식과 bfs를 사용하여 해결하였습니다.

 

브루트포스로 설치할 벽의 모든 경우를 구하였고, 3개의 벽을 설치하면 bfs를 돌려서 바이러스를 최대한 퍼뜨린 후에 안전 영역의 갯수를 구하였습니다.

 

 

[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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
 
queue<pair<intint> > q;
int direct[4][2= { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };
bool visit[8][8];
int list[8][8];
int N, M, ans;
 
void bfs() {
    queue<pair<intint> > nq = q;
    int sum = 0;
    while (!nq.empty()) {
        int x = nq.front().first;
        int y = nq.front().second;
        nq.pop();
        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[nx][ny] != 0 || visit[nx][ny]) continue;
            visit[nx][ny] = true;
            nq.push({ nx,ny });
        }
    }
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (list[i][j] != 0 || visit[i][j]) continue;
            sum++;
        }
    }
 
    ans = max(ans, sum);
}
 
void func(int x, int y, int cnt) {
    if (cnt == 3) {
        bfs();
        memset(visit, falsesizeof(visit));
        return;
    }
 
    int sx = x;
    int sy = y;
    for (int i = sx; i < N; i++) {
        for (int j = sy; j < M; j++) {
            if (list[i][j] != 0continue;
 
            list[i][j] = 1;
            if (j == M - 1) func(i + 10, cnt + 1);
            else func(i, j + 1, cnt + 1);
            list[i][j] = 0;
        }
        sy = 0;
    }
}
 
void input() {
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> list[i][j];
 
            if (list[i][j] == 2) {
                q.push({ i,j });
                visit[i][j] = true;
            }
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func(000);
    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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[][] = new int[8][8];
    static Deque<int[]> virus = new ArrayDeque<>();
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int N, M, ans;
 
    static void bfs() {
        Deque<int[]> dq = new ArrayDeque<>();
        boolean visit[][] = new boolean[8][8];
        dq.addAll(virus);
        Iterator<int[]> iter = dq.iterator();
        while (iter.hasNext()) {
            int xy[] = iter.next();
            visit[xy[0]][xy[1]] = true;
        }
 
        while (!dq.isEmpty()) {
            int x = dq.peek()[0];
            int y = dq.poll()[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 >= M)
                    continue;
                if (visit[nx][ny] || list[nx][ny] == 1)
                    continue;
 
                dq.add(new int[] { nx, ny });
                visit[nx][ny] = true;
            }
        }
 
        int cnt = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (visit[i][j] || list[i][j] != 0)
                    continue;
 
                cnt++;
            }
        }
 
        ans = Math.max(ans, cnt);
    }
 
    static void func(int sx, int sy, int cnt) {
        if (cnt == 3) {
            bfs();
            return;
        }
 
        int i = sx;
        int j = sy;
        for (; i < N; i++) {
            for (; j < M; j++) {
                if (list[i][j] != 0)
                    continue;
 
                list[i][j] = 1;
                if (j == M - 1)
                    func(i + 10, cnt + 1);
                else
                    func(i, j + 1, cnt + 1);
                list[i][j] = 0;
            }
            j = 0;
        }
    }
 
    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++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
                if (list[i][j] == 2) {
                    virus.add(new int[] { i, j });
                }
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(000);
        System.out.println(ans);
    }
}
cs

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

boj 10026 적록색약  (0) 2021.02.13
boj 2206 벽 부수고 이동하기  (0) 2021.02.13
boj 20304 비밀번호 제작  (0) 2021.02.08
boj 2606 바이러스  (0) 2021.02.03
boj 1012 유기농 배추  (0) 2021.02.03

www.acmicpc.net/problem/2559

 

2559번: 수열

첫째 줄에는 두 개의 정수 N과 K가 한 개의 공백을 사이에 두고 순서대로 주어진다. 첫 번째 정수 N은 온도를 측정한 전체 날짜의 수이다. N은 2 이상 100,000 이하이다. 두 번째 정수 K는 합을 구하기

www.acmicpc.net

모든 연속적인 K일 간의 최대 온도의 합을 출력하는 문제입니다.

우선 dp를 이용하여 N일 간 측정한 모든 온도의 연속합을 저장합니다.

그 다음 투 포인터 방식으로 l = 1, r = K으로 시작하여 dp[r] - dp[l - 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
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.BufferedReader;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[], dp[];
    static int N, K, ans = Integer.MIN_VALUE;
 
    static void func() {
        int l = 1;
        int r = K;
 
        while (r <= N) {
            ans = Math.max(ans, dp[r] - dp[l - 1]);
 
            r++;
            l++;
        }
 
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        list = new int[N + 1];
        dp = new int[N + 1];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
            dp[i] = dp[i - 1+ list[i];
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 1253 좋다  (0) 2021.10.21
boj 9024 두 수의 합  (0) 2021.10.21
boj 17609 회문  (0) 2021.03.29
boj 1806 부분합  (0) 2021.01.22
boj 2003 수들의 합 2  (0) 2021.01.22

www.acmicpc.net/problem/11438

 

11438번: LCA 2

첫째 줄에 노드의 개수 N이 주어지고, 다음 N-1개 줄에는 트리 상에서 연결된 두 정점이 주어진다. 그 다음 줄에는 가장 가까운 공통 조상을 알고싶은 쌍의 개수 M이 주어지고, 다음 M개 줄에는 정

www.acmicpc.net

 

emoney96.tistory.com/114

 

boj 11437 LCA

www.acmicpc.net/problem/11437 11437번: LCA 첫째 줄에 노드의 개수 N이 주어지고, 다음 N-1개 줄에는 트리 상에서 연결된 두 정점이 주어진다. 그 다음 줄에는 가장 가까운 공통 조상을 알고싶은 쌍의 개수 M

emoney96.tistory.com

위의 문제와 같은 풀이방법입니다.

두 문제의 차이는 N과 M의 입력범위가 훨씬 커진다는 점입니다.

N에 맞춰서 배열크기를 더 크게잡았습니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
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> list[] = new ArrayList[100001];
    static boolean visit[] = new boolean[100001];
    static int depth[] = new int[100001];
    static int parent[][] = new int[100001][21];
    static int N, M;
 
    static 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].get(i);
 
            if (visit[next])
                continue;
 
            parent[next][0= v;
            dfs(next, d + 1);
        }
    }
 
    static void func() {
        dfs(11);
        for (int j = 1; j < 21; j++) {
            for (int i = 1; i <= N; i++) {
                parent[i][j] = parent[parent[i][j - 1]][j - 1];
            }
        }
    }
 
    static int lca(int x, int y) {
        if (depth[x] > depth[y]) {
            int tmp = x;
            x = y;
            y = tmp;
        }
 
        for (int i = 20; i >= 0; i--) {
            if (depth[y] - depth[x] >= (1 << i)) {
                y = parent[y][i];
            }
        }
 
        if (x == y)
            return x;
 
        for (int i = 20; i >= 0; i--) {
            if (parent[x][i] != parent[y][i]) {
                x = parent[x][i];
                y = parent[y][i];
            }
        }
 
        return parent[x][0];
    }
 
    static void solve() throws Exception {
        int u, v;
        st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        while (M-- > 0) {
            st = new StringTokenizer(br.readLine());
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
            sb.append(lca(u, v) + "\n");
        }
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        int u, v;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        for (int i = 1; i <= N; i++)
            list[i] = new ArrayList<>();
 
        for (int i = 0; i < N - 1; i++) {
            st = new StringTokenizer(br.readLine());
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
 
            list[u].add(v);
            list[v].add(u);
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        solve();
    }
}
cs

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

boj 1626 두 번째로 작은 스패닝 트리  (0) 2021.04.02
boj 15481 그래프와 MST  (0) 2021.04.01
boj 15480 LCA와 쿼리  (0) 2021.02.14
boj 11437 LCA  (0) 2021.02.11
boj 13116 30번  (0) 2021.02.09

www.acmicpc.net/problem/11437

 

11437번: LCA

첫째 줄에 노드의 개수 N이 주어지고, 다음 N-1개 줄에는 트리 상에서 연결된 두 정점이 주어진다. 그 다음 줄에는 가장 가까운 공통 조상을 알고싶은 쌍의 개수 M이 주어지고, 다음 M개 줄에는 정

www.acmicpc.net

 

 

LCA 알고리즘으로 해결하였습니다.

 

정점이 N개이고, N - 1개의 간선정보가 입력주어 주어집니다.

u와 v를 서로 연결시켜주고 루트노드인 1부터 dfs를 돌려서 각 노드의 높이를 먼저 구해줍니다.

높이를 구하는 과정에서 자식노드가 next로 나오는데 next의 첫번째 조상노드를 v로 저장해둡니다.

 

dfs순회가 끝나면 이제 각 노드의 2^N번째 조상노드를 저장해줍니다.

첫번째 조상노드부터 차례대로 저장하여 순회하면 시간적으로 비효율적이고,

1, 2, 4, 8, ~ 2^N번째 조상노드만 저장해줘도 모든 조상노드를 탐색할 수 있습니다.

 

그리고 u, v 정점이 입력으로 들어오면 lca함수를 통해 최소 공통 조상노드를 구해줍니다.

먼저 노드의 depth가 높은쪽을 y에 맞춘 후에 y노드의 높이를 x와 같게 맞춰줍니다.

그 다음 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
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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
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> list[] = new ArrayList[50001];
    static boolean visit[];
    static int parent[][] = new int[50001][17];
    static int depth[] = new int[50001];
    static int N, M;
 
    static void dfs(int v, int d) {
        visit[v] = true;
        depth[v] = d;
 
        for (int i = 0; i < list[v].size(); i++) {
            int next = list[v].get(i);
 
            if (visit[next])
                continue;
 
            parent[next][0= v;
            dfs(next, d + 1);
        }
    }
 
    static void func() {
        dfs(11);
        for (int j = 1; j < 17; j++) {
            for (int i = 1; i <= N; i++) {
                parent[i][j] = parent[parent[i][j - 1]][j - 1];
            }
        }
    }
 
    static int lca(int x, int y) {
        if (depth[x] > depth[y]) {
            int tmp = x;
            x = y;
            y = tmp;
        }
 
        for (int i = 16; i >= 0; i--) {
            if (depth[y] - depth[x] >= (1 << i)) {
                y = parent[y][i];
            }
        }
 
        if (y == x)
            return x;
 
        for (int i = 16; i >= 0; i--) {
            if (parent[x][i] != parent[y][i]) {
                x = parent[x][i];
                y = parent[y][i];
            }
        }
 
        return parent[x][0];
    }
 
    static void solve() throws Exception {
        int u, v;
        st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        while (M-- > 0) {
            st = new StringTokenizer(br.readLine());
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
            sb.append(lca(u, v) + "\n");
        }
        
        System.out.print(sb.toString());
    }
 
    static void input() throws Exception {
        int u, v;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        visit = new boolean[N + 1];
        for (int i = 1; i <= N; i++)
            list[i] = new ArrayList<>();
 
        for (int i = 0; i < N - 1; i++) {
            st = new StringTokenizer(br.readLine());
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
            list[u].add(v);
            list[v].add(u);
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        solve();
    }
}
cs

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

boj 1626 두 번째로 작은 스패닝 트리  (0) 2021.04.02
boj 15481 그래프와 MST  (0) 2021.04.01
boj 15480 LCA와 쿼리  (0) 2021.02.14
boj 11438 LCA 2  (0) 2021.02.11
boj 13116 30번  (0) 2021.02.09

+ Recent posts