www.acmicpc.net/problem/5557

 

5557번: 1학년

상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀

www.acmicpc.net

조합과 dp를 이용하여 해결하였습니다.

 

0 ~ N - 2를 조합하여 N - 1번째 값이 나오는 갯수를 출력하는 문제입니다.

단, 더하거나 빼는 과정에서 음수나 20보다 커지면 안됩니다.

저는 배열을 dp[idx][now] => (현재 idx에서 값이 now일 경우의 수)

 

0번 인덱스의 값은 무조건 +로 들어가니 그 다음인 1번 인덱스와, list[0]으로 재귀를 돌려줍니다.

now + list[idx] <= 20 일 경우에만 더한 값을 다음으로 넘겨주고

now - list[idx]>=0 일 경우에만 뺀 값을 다음으로 넘겨줍니다.

 

인덱스가 N - 1이 되면 지금까지 구한 값이 list[N - 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
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 long dp[][];
    static int N, list[];
 
    static long func(int idx, int now) {
        if (idx == N - 1) {
            if (now == list[idx])
                return dp[idx][now] = 1;
            return dp[idx][now] = 0;
        }
 
        if (dp[idx][now] != -1)
            return dp[idx][now];
 
        dp[idx][now] = 0;
 
        if (now + list[idx] <= 20)
            dp[idx][now] += func(idx + 1, now + list[idx]);
 
        if (now - list[idx] >= 0)
            dp[idx][now] += func(idx + 1, now - list[idx]);
 
        return dp[idx][now];
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N];
        dp = new long[N][21];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    static void init() {
        for (int i = 0; i < N; i++) {
            Arrays.fill(dp[i], -1);
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        init();
        System.out.println(func(1, list[0]));
    }
}
cs

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

boj 5569 출근 경로  (0) 2021.02.06
boj 1010 다리 놓기  (0) 2021.02.05
boj 5573 산책  (0) 2021.02.04
boj 17528 Two Machines  (0) 2021.01.28
boj 9657 돌 게임 3  (0) 2021.01.27

www.acmicpc.net/problem/5573

 

5573번: 산책

첫째 줄에 H, W, N이 주어진다. (1 ≤ H,W ≤ 1000, 1 ≤ N ≤ 107) 둘째 줄부터 H개 줄에는 W개 정수가 주어진다. 이 정수는 상근이가 교차로에 써 놓은 문자의 정보이다. 0은 아래쪽을 의미하는 '아', 1은

www.acmicpc.net

1000 * 1000에 10000000번 산책을 하기때문에 시뮬레이션으로 접근하다가는 무조건 시간초과 뜹니다.

저는 방향정보를 dp를 이용하여 N - 1번까지 산책한 이후의 경로를 만들어 놓고 마지막 한 번 산책하는 방식으로 하였습니다.

 

dp에는 N - 1번의 산책동안 (x, y)에 몇 번 지나갔는지 표시하는데 사용하였습니다.

여기서 문제에서 산책하는 규칙이 있습니다.

0은 아래쪽, 1은 오른쪽 방향으로 가며 한 번 어떤 방향으로 가면 그 다음번 산책에서는 반드시 다른 방향으로 이동하게 되어있습니다.

따라서 dp[x][y]는 dp[x-1][y]에서 방문한 횟수의 1/2 + dp[x][y-1]에서 방문한 횟수의 1/2를 한 값입니다.

여기서 추가해야할 것이 dp[x-1][y], dp[x][y-1]이 홀수일 때 방향에 따라서도 방문횟수가 추가될 수 있습니다.

 

(x-1, y) 즉, 위쪽 방향에서 밑쪽으로 지나가려면 경로는 아래쪽 방향이 되어있어야합니다.

(x, y-1) 즉, 왼쪽 방향에서 오른쪽으로 지나가려면 경로는 오른쪽 방향이 되어있어야합니다.

위의 두가지를 추가하기 위해 처음에 받은 list[x-1][y], list[x][y-1]을 확인해야합니다.

 

(x-1, y)의 경우 처음 방향인 list[x-1][y]이 0이면 홀수일 때 1을 추가해줍니다.

(x, y-1)의 경우 처음 방향인 list[x][y-1]이 1이면 짝수일 때 1을 추가해줍니다.

 

이렇게 dp를 다 구하고 나면 이를 이용하여 산책경로를 모두 바꿔야합니다.

dp[x][y]가 짝수인 위치는 방향을 바꿀 필요 없고, 홀수인 위치에만 방향을 바꿔줍니다.

 

마지막으로 x=1, 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
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 list[][] = new int[1001][1001];
    static int H, W, N;
 
    static void solve() {
        int x = 1;
        int y = 1;
        while (true) {
            if (list[x][y] == 1)
                y++;
            else
                x++;
 
            if (x > H || y > W)
                break;
        }
 
        System.out.println(x + " " + y);
    }
 
    static void func() {
        int dp[][] = new int[H + 1][W + 1];
        for (int i = 1; i <= H; i++) {
            for (int j = 1; j <= W; j++) {
                if (i == 1 && j == 1) {
                    dp[i][j] = N - 1;
                    continue;
                }
                
                dp[i][j] = dp[i - 1][j] / 2 + dp[i][j - 1/ 2;
 
                if (dp[i - 1][j] % 2 == 1 && list[i - 1][j] == 0)
                    dp[i][j]++;
                if (dp[i][j - 1] % 2 == 1 && list[i][j - 1== 1)
                    dp[i][j]++;
            }
        }
 
        for (int i = 1; i <= H; i++) {
            for (int j = 1; j <= W; j++) {
                if (dp[i][j] % 2 == 0)
                    continue;
 
                list[i][j] = 1 - list[i][j];
            }
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        H = Integer.parseInt(st.nextToken());
        W = Integer.parseInt(st.nextToken());
        N = Integer.parseInt(st.nextToken());
 
        for (int i = 1; i <= H; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= W; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        solve();
    }
}
cs

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

boj 1010 다리 놓기  (0) 2021.02.05
boj 5557 1학년  (0) 2021.02.05
boj 17528 Two Machines  (0) 2021.01.28
boj 9657 돌 게임 3  (0) 2021.01.27
boj 2096 내려가기  (0) 2021.01.22

www.acmicpc.net/problem/2243

 

2243번: 사탕상자

첫째 줄에 수정이가 사탕상자에 손을 댄 횟수 n(1≤n≤100,000)이 주어진다. 다음 n개의 줄에는 두 정수 A, B, 혹은 세 정수 A, B, C가 주어진다. A가 1인 경우는 사탕상자에서 사탕을 꺼내는 경우이다.

www.acmicpc.net

사탕의 맛이 1 ~ 1000000 까지 있습니다.

저는 맛을 인덱스로 하여 세그먼트 트리를 사용하여 구간 합을 구현하였습니다.

 

A가 1일 때, B는 꺼낼 사탕의 순위입니다.

A가 2일 때, B는 넣는 사탕의 맛이고, C는 갯수이며 양수면 넣는 경우, 음수면 빼는 경우입니다.

 

A = 2가 들어오면 B 인덱스에 C만큼 추가하면 되겠고

A = 1이 들어오면 사탕의 순위를 이분탐색으로 찾습니다.

 

이분탐색은 세그먼트 트리의 값을 이용하여 범위를 찾습니다.

x가 왼쪽 자식노드의 수보다 작거나 같으면 (tree[node * 2] >= x) l ~ m 범위로 내려가고 (더 낮은 구역을 탐색)

x가 왼쪽 자식노드의 수보다 크면 (tree[node * 2 < x) m + 1 ~ r의 범위로 내려갑니다. (더 높은 구역을 탐색)

이 때 m + 1 ~ r의 범위로 이동할 때 오른쪽 자식노드의 순위를 판단해야 하기때문에 x - tree[node * 2] 한 값을 보내줍니다.

 

마지막으로 l == r 구역에 도달하면 사탕을 한개 빼줘야하므로 update를 해주고 찾은 인덱스를 리턴해줍니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static final int MAX = 1000000;
    static int tree[] = new int[(MAX + 1* 4];
    static int N;
 
    static void update(int node, int s, int e, int idx, int diff) {
        if (idx < s || idx > e)
            return;
 
        if (s == e) {
            tree[node] += diff;
            return;
        }
 
        tree[node] += diff;
        int m = (s + e) / 2;
        update(node * 2, s, m, idx, diff);
        update(node * 2 + 1, m + 1, e, idx, diff);
    }
 
    static int binarysearch(int node, int l, int r, int x) {
        if (l == r) {
            update(11, MAX, l, -1);
            return l;
        }
 
        int m = (l + r) / 2;
        if (tree[node * 2>= x)
            return binarysearch(node * 2, l, m, x);
        else
            return binarysearch(node * 2 + 1, m + 1, r, x - tree[node * 2]);
    }
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        StringBuffer sb = new StringBuffer();
 
        N = Integer.parseInt(st.nextToken());
        while (N-- > 0) {
            st = new StringTokenizer(br.readLine());
            int type = Integer.parseInt(st.nextToken());
 
            if (type == 1) {
                int a = Integer.parseInt(st.nextToken());
                sb.append(binarysearch(11, MAX, a)).append("\n");
            } else {
                int a = Integer.parseInt(st.nextToken());
                int b = Integer.parseInt(st.nextToken());
 
                update(11, MAX, a, b);
            }
        }
 
        System.out.println(sb.toString());
    }
}
cs

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

boj 14438 수열과 쿼리 17  (0) 2021.02.21
boj 13537 수열과 쿼리 1  (0) 2021.02.21
boj 6549 히스토그램에서 가장 큰 직사각형  (0) 2021.02.19
boj 2104 부분배열 고르기  (0) 2021.02.19
boj 2042 구간 합 구하기  (0) 2021.01.23

www.acmicpc.net/problem/2493

 

2493번: 탑

첫째 줄에 탑의 수를 나타내는 정수 N이 주어진다. N은 1 이상 500,000 이하이다. 둘째 줄에는 N개의 탑들의 높이가 직선상에 놓인 순서대로 하나의 빈칸을 사이에 두고 주어진다. 탑들의 높이는 1

www.acmicpc.net

탑 A의 왼쪽에 있는 탑들 중에서 탑 A보다 더 큰 높이의 탑들 중 가장 오른쪽의 탑의 위치를 구하는 문제입니다.

배열크기를 너무 높게잡으면 메모리초과까지 나올 수 있어서 초기에 배열크기를 잘 잡아야합니다.

N이 500000까지 들어오기때문에 N^2으로는 무조건 시간초과뜹니다

 

먼저 입력으로 주어지는 탑의 높이를 list에 저장하였고, 1번부터 N번까지 순회를 합니다.

 

스택에는 인덱스를 유지합니다.

i번 위치에서 스택이 비어있지 않고, list[top]이 list[i]보다 작을동안 pop을 해줍니다.

그 후에 스택이 비어있으면 0, 아니면 스택의 top을 출력하시면 됩니다.

 

 

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
package BOJ.data_structure;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
 
public class Boj2493 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static Stack<Integer> s = new Stack<>();
    static int list[];
    static int N;
 
    static void func() {
        for (int i = 0; i < N; i++) {
            while (!s.isEmpty() && list[s.peek()] < list[i])
                s.pop();
 
            if (s.isEmpty()) {
                s.push(i);
                sb.append("0 ");
            } else {
                sb.append(s.peek() + 1 + " ");
                s.push(i);
            }
        }
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 1918 후위 표기식  (0) 2021.02.05
boj 1935 후위 표기식2  (0) 2021.02.05
boj 6416 트리인가?  (0) 2021.02.04
boj 3190 뱀  (0) 2021.02.02
boj 2346 풍선 터뜨리기  (0) 2021.02.02

www.acmicpc.net/problem/1837

 

1837번: 암호제작

원룡이는 한 컴퓨터 보안 회사에서 일을 하고 있다. 그러던 도중, 원룡이는 YESWOA.COM 으로부터 홈페이지 유저들의 비밀키를 만들라는 지시를 받았다. 원룡이는 비밀 키를 다음과 같은 방법으로

www.acmicpc.net

BigInteger를 사용하는 문제입니다.

P는 소수의 곱으로 이루어져있지만 10^100이라는 수가 입력으로 주어집니다.

K는 P가 좋은 암호인지, 좋지 않은 암호인지 구별하는 수이며 1000000까지 주어집니다.

 

P를 나타내는 소수 p, q 중에 하나라도 K보다 작으면 이 암호P는 좋지 않은 암호입니다.

하지만 P가 너무 큰 수이기 때문에 소수를 직접 구할 수 없으므로 K범위 내의 소수를 모두 구하여

 

구한 소수들 중 P와 나머지 연산을 해서 0이 되는 수가 있으면 BAD, 없으면 GOOD를 출력하였습니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static BigInteger P, K;
    static boolean sosuchk[] = new boolean[1000001];
    static Set<BigInteger> sosu = new TreeSet<>();
    static int k;
 
    static void func() {
        Iterator<BigInteger> iter = sosu.iterator();
        while (iter.hasNext()) {
            BigInteger a = iter.next();
            if (a.compareTo(K) >= 0)
                break;
 
            if (P.mod(a).equals(new BigInteger("0"))) {
                System.out.println("BAD " + a);
                return;
            }
        }
 
        System.out.println("GOOD");
    }
 
    static void init() {
        for (int i = 2; i <= 1000000; i++) {
            if (sosuchk[i])
                continue;
 
            sosu.add(new BigInteger(Integer.toString(i)));
            for (int j = 2; i * j <= 1000000; j++) {
                if (sosuchk[i * j])
                    continue;
 
                sosuchk[i * j] = true;
            }
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
 
        P = new BigInteger(st.nextToken());
        k = Integer.parseInt(st.nextToken());
        K = new BigInteger(Integer.toString(k));
    }
 
    public static void main(String[] args) throws Exception {
        init();
        input();
        func();
    }
}
cs

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

boj 13136 Do Not Touch Anything  (0) 2022.10.25
boj 15740 A+B - 9  (0) 2021.01.31
boj 1002 터렛  (0) 2021.01.27

www.acmicpc.net/problem/6416

 

6416번: 트리인가?

트리는 굉장히 잘 알려진 자료 구조이다. 트리를 만족하는 자료 구조는 비어 있거나(노드의 개수가 0개), 노드의 개수가 1개 이상이고 방향 간선이 존재하며 다음과 같은 조건을 만족해야 한다.

www.acmicpc.net

자바라서 입력 받는거부터 좀 힘들었습니다..

다행히 검색으로 다음 토큰이 있는지 확인하는 st.hasMoreTokens() 라는 것을 찾아서 입력을 받았습니다.

 

이 문제는 u v 로 입력이 주어지고 이는 u->v를 뜻합니다.

트리이기 때문에 방향 그래프이고 한 방향으로만 향합니다. 즉, v->u는 안됩니다.

 

이 문제에서는 트리가 아닌 조건들을 모두 체크해주어야합니다.

1. 부모노드가 2개 이상인지

2. 루트노드가 1개가 아닌지 (0개이거나 2개 이상인지)

3. 사이클이 있는지

 

먼저 1번, 부모노드 확인입니다.

입력을 받으면서 자식으로 등록되는 노드(v)들을 Set을 이용하여 저장했고, 만약에 Set에 있는 값을 다시 넣게 된다면 자식으로 등록이 두번 됩니다. 즉 부모노드가 2개이상이 된다는 뜻입니다. => not tree

 

2번, 루트노드 확인입니다.

입력으로 주어지는 모든 부모노드(u)를 Set을 이용하여 저장했고, 만약에 Set에 있는 원소 중에 자식으로 등록되어있지 않으면 루트노드입니다.

만약 이러한 노드가 없거나 2개 이상이면 not tree입니다.

 

3번, 사이클 확인입니다.

map을 이용하여 Key는 부모노드(u), Value는 자식노드들(v)을 Integer, ArrayList<Integer>로 구현하였습니다.

사이클 확인은 dfs로 순회하여 next가 이미 방문한 노드인지 확인하였고, 이미 방문한 노드면 사이클이 있다는 말이기 때문에 not tree입니다.

 

3번의 확인이 끝나고 셋 다 아니라면 tree입니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
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 Map<Integer, ArrayList<Integer>> m = new HashMap<>();
    static Set<Integer> findRoot = new HashSet<>();
    static Set<Integer> child = new HashSet<>();
    static Set<Integer> visit = new HashSet<>();
    static boolean tworoot, twoparents, cycle;
    static int u, v, root;
 
    static void dfs(int x) {
        visit.add(x);
 
        ArrayList<Integer> graph = m.get(x);
        if (graph == null)
            return;
 
        for (int i = 0; i < graph.size(); i++) {
            int next = graph.get(i);
 
            if (visit.contains(next)) {
                cycle = true;
                return;
            }
 
            dfs(next);
            if (cycle)
                return;
        }
    }
 
    static void rootFinding() {
        Iterator<Integer> iter = findRoot.iterator();
        while (iter.hasNext()) {
            int x = iter.next();
 
            if (!child.contains(x)) {
                if (root != 0) {
                    tworoot = true;
                    return;
                }
                root = x;
            }
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        while (true) {
            while (!st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
 
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
            if (u == 0 || u == -1)
                return;
 
            if (m.containsKey(u)) {
                m.get(u).add(v);
            } else {
                ArrayList<Integer> tmp = new ArrayList<>();
                tmp.add(v);
                m.put(u, tmp);
            }
            if (child.contains(v))
                twoparents = true;
            else
                child.add(v);
 
            findRoot.add(u);
        }
    }
 
    static void clear() {
        m.clear();
        findRoot.clear();
        child.clear();
        visit.clear();
        twoparents = false;
        tworoot = false;
        cycle = false;
        root = 0;
    }
 
    public static void main(String[] args) throws Exception {
        for (int T = 1;; T++) {
            input();
            if (u == -1)
                break;
 
            sb.append("Case " + T + " is ");
            if (child.isEmpty()) {
                sb.append("a tree.\n");
                continue;
            }
            if (twoparents) {
                sb.append("not a tree.\n");
                clear();
                continue;
            }
 
            rootFinding();
            if (root == 0 || tworoot) {
                sb.append("not a tree.\n");
                clear();
                continue;
            }
 
            dfs(root);
            if (cycle)
                sb.append("not a tree.\n");
            else
                sb.append("a tree.\n");
 
            clear();
        }
 
        System.out.println(sb.toString());
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 1935 후위 표기식2  (0) 2021.02.05
boj 2493 탑  (0) 2021.02.04
boj 3190 뱀  (0) 2021.02.02
boj 2346 풍선 터뜨리기  (0) 2021.02.02
boj 5397 키로거  (0) 2021.02.02

www.acmicpc.net/problem/2606

 

2606번: 바이러스

첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어

www.acmicpc.net

처음에 1번 컴퓨터가 바이러스에 걸리고 이 컴퓨터로 인해 바이러스에 걸리는 컴퓨터가 몇 대인지 출력하는 문제입니다.

 

이 문제는 간단한 bfs로 해결할 수 있습니다.

입력으로 u와 v가 주어지면 둘이 연결되어있다는 말입니다.

이 그래프는 양방향 그래프이기 때문에 u의 간선에도 v를 추가하고, v의 간선에도 u를 추가해야합니다.

 

그 다음 1번부터 시작하여 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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
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 ArrayList<Integer> list[];
    static boolean visit[];
    static int N, M, ans;
 
    static void bfs() {
        Queue<Integer> q = new LinkedList<>();
        q.add(1);
        visit[1= true;
        while (!q.isEmpty()) {
            int v = q.peek();
 
            q.remove();
 
            for (int i = 0; i < list[v].size(); i++) {
                int next = list[v].get(i);
 
                if (visit[next])
                    continue;
 
                q.add(next);
                visit[next] = true;
                ans++;
            }
        }
    }
 
    static void input() throws Exception {
        int u, v;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new ArrayList[N + 1];
        visit = new boolean[N + 1];
        for (int i = 1; i <= N; i++) {
            list[i] = new ArrayList<>();
        }
 
        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());
 
            list[u].add(v);
            list[v].add(u);
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        bfs();
        System.out.println(ans);
    }
}
cs

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

boj 14502 연구소  (0) 2021.02.12
boj 20304 비밀번호 제작  (0) 2021.02.08
boj 1012 유기농 배추  (0) 2021.02.03
boj 16956 늑대와 양  (0) 2021.02.03
boj 20419 화살표 미로 (Easy)  (0) 2021.01.23

www.acmicpc.net/problem/1012

 

1012번: 유기농 배추

차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 

www.acmicpc.net

배추영역 하나에 지렁이 한마리가 들어가고 최종적으로 배추밭에 필요한 지렁이의 수를 구하는 문제이며

탐색을 통해 배추영역의 갯수를 구하는 문제입니다.

 

저는 bfs를 사용했습니다.

입력으로 배추의 위치가 X, Y로 주어지면 list[X][Y] = 1로 표시합니다.

모든 입력을 다 받고 2중 for문을 돌려서 해당 칸이 1이면서 아직 방문하지 않은 위치면 그 위치를 시작으로 bfs를 돌립니다.

 

bfs로 현재 위치에서 주변에 1이 있는 좌표들을 큐에 넣고 중복체크를 해줍니다.

bfs 탐색이 종료되면 한 구역 탐색이 끝난 것이므로 ans를 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
89
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 StringBuffer sb = new StringBuffer();
    static boolean visit[][];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int list[][];
    static int N, M, K, ans;
 
    static void print() {
        sb.append(ans + "\n");
        ans = 0;
    }
 
    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.peek()[1];
 
            q.remove();
 
            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] == 0)
                    continue;
 
                q.add(new int[] { nx, ny });
                visit[nx][ny] = true;
            }
        }
    }
 
    static void func() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (list[i][j] == 1) {
                    if (visit[i][j])
                        continue;
 
                    bfs(i, j);
                    ans++;
                }
            }
        }
    }
 
    static void input() throws Exception {
        int u, v;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        list = new int[N][M];
        visit = new boolean[N][M];
 
        while (K-- > 0) {
            st = new StringTokenizer(br.readLine());
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
 
            list[u][v] = 1;
        }
    }
 
    public static void main(String[] args) throws Exception {
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            input();
            func();
            print();
        }
        
        System.out.println(sb.toString());
    }
}
cs

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

boj 20304 비밀번호 제작  (0) 2021.02.08
boj 2606 바이러스  (0) 2021.02.03
boj 16956 늑대와 양  (0) 2021.02.03
boj 20419 화살표 미로 (Easy)  (0) 2021.01.23
boj 2638 치즈  (0) 2021.01.22

www.acmicpc.net/problem/16956

 

16956번: 늑대와 양

크기가 R×C인 목장이 있고, 목장은 1×1 크기의 칸으로 나누어져 있다. 각각의 칸에는 비어있거나, 양 또는 늑대가 있다. 양은 이동하지 않고 위치를 지키고 있고, 늑대는 인접한 칸을 자유롭게

www.acmicpc.net

 

문제 분류는 bfs로 되어있지만 bfs를 사용하지 않아도 해결 가능한 문제입니다.

저는 bfs방식으로 양의 위치를 큐에 담아서 하나씩 꺼내 확인하는 방법과

2중 for문을 이용해서 양의 위치에서 확인하는 방법으로 2가지로 해결해 보았습니다.

 

두 방법 모두 양의 위치에서 상, 하, 좌, 우 방향에 늑대가 있는지 확인합니다.

늑대가 있으면 0출력후 리턴, 없으면 놓을 수 있는 모든 방향에 울타리를 설치합니다.

 

문제가 스페셜저지이기 때문에 예제와 답이 다르게 나와도 늑대가 양이 있는 칸으로 갈수없다면 정답으로 할 수 있습니다. (물론 첫째줄에 출력하는 0과 1은 맞아야합니다.)

 

[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
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 chk;
    static char list[][];
    static int N, M;
 
    static void print() {
        if (chk) {
            System.out.println(0);
            return;
        }
 
        StringBuffer sb = new StringBuffer();
        sb.append("1\n");
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                sb.append(list[i][j]);
            }
            sb.append("\n");
        }
 
        System.out.println(sb.toString());
    }
 
    static void func() {
        while (!q.isEmpty()) {
            int x = q.peek()[0];
            int y = q.peek()[1];
            q.remove();
 
            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] == 'S' || list[nx][ny] == 'D')
                    continue;
                if (list[nx][ny] == 'W') {
                    chk = true;
                    break;
                }
 
                list[nx][ny] = 'D';
            }
 
            if (chk)
                break;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new char[N][M];
 
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = st.nextToken().toCharArray();
            for (int j = 0; j < M; j++) {
                if (list[i][j] == 'S') {
                    q.add(new int[] { i, j });
                }
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

 

[2중 for문을 통한 탐색]

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
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 direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static char list[][];
    static int N, M;
    static boolean chk;
 
    static void print() {
        if (chk) {
            System.out.println(0);
            return;
        }
 
        StringBuffer sb = new StringBuffer();
        sb.append("1\n");
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                sb.append(list[i][j]);
            }
            sb.append("\n");
        }
 
        System.out.println(sb.toString());
    }
 
    static void func() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (list[i][j] == 'S') {
                    for (int k = 0; k < 4; k++) {
                        int nx = i + direct[k][0];
                        int ny = j + direct[k][1];
 
                        if (nx < 0 || ny < 0 || nx >= N || ny >= M)
                            continue;
                        if (list[nx][ny] == 'S' || list[nx][ny] == 'D')
                            continue;
                        if (list[nx][ny] == 'W') {
                            chk = true;
                            return;
                        }
 
                        list[nx][ny] = 'D';
                    }
                }
            }
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new char[N][M];
 
        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();
        print();
    }
}
cs

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

boj 2606 바이러스  (0) 2021.02.03
boj 1012 유기농 배추  (0) 2021.02.03
boj 20419 화살표 미로 (Easy)  (0) 2021.01.23
boj 2638 치즈  (0) 2021.01.22
boj 17142 연구소 3  (0) 2021.01.22

www.acmicpc.net/problem/3190

 

3190번: 뱀

 'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임

www.acmicpc.net

입력으로 보드의 크기와 사과의 갯수, 좌표, 방향 회전 정보가 주어집니다.

여기서 좌표는 (1, 1) ~ (N, N)으로 주어지기 때문에 주어지는 크기에 맞게 접근을 해야합니다.

(그거때문에 런타임에러가 떴었습니다... 문제좀 제대로 읽어봐야하는데..)

 

저는 뱀의 위치를 덱으로 구현하여 덱의 맨 앞에는 뱀의 머리, 맨 뒤에는 뱀의 꼬리로 두었습니다.

그리고 뱀의 방향전환 정보가 최대 10000개라서 char배열을 이용하여 하였습니다.

 

뱀을 움직일 때는

1. 뱀이 움직인다. (움직인 곳으로 push)

2. 다음 칸이 사과면 꼬리가 위치한 칸을 그대로 둔다. (길이 +1)

3. 다음 칸이 사과가 아닌 빈칸이면 꼬리가 위치한 칸을 비운다. (길이 그대로)

4. 뱀을 움직이고 해당 시간에 회전명령이 있으면 회전한다.

5. 다음 칸이 뱀이 있는 위치이거나 맵 밖이면 게임이 끝난다. (T 출력)

위의 규칙대로 움직여주시면 됩니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static char ch[] = new char[10001];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int list[][];
    static Deque<int[]> dq = new ArrayDeque<>();
    static int N, K, L;
 
    static void func() {
        int idx = 0;
        dq.addLast(new int[] { 11 });
        list[1][1= 1;
        for (int T = 1;; T++) {
            int x = dq.peekFirst()[0];
            int y = dq.peekFirst()[1];
 
            int nx = x + direct[idx][0];
            int ny = y + direct[idx][1];
            if (nx <= 0 || ny <= 0 || nx > N || ny > N) {
                System.out.println(T);
                return;
            }
 
            if (list[nx][ny] == 2) {
                dq.addFirst(new int[] { nx, ny });
            } else if (list[nx][ny] == 0) {
                dq.addFirst(new int[] { nx, ny });
                list[dq.peekLast()[0]][dq.peekLast()[1]] = 0;
                dq.removeLast();
            } else {
                System.out.println(T);
                return;
            }
 
            if (ch[T] == 'L')
                idx = (idx + 3) % 4;
            else if (ch[T] == 'D')
                idx = (idx + 1) % 4;
 
            list[nx][ny] = 1;
        }
    }
 
    static void input() throws Exception {
        int x, y;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N + 1][N + 1];
 
        st = new StringTokenizer(br.readLine());
        K = Integer.parseInt(st.nextToken());
        while (K-- > 0) {
            st = new StringTokenizer(br.readLine());
            x = Integer.parseInt(st.nextToken());
            y = Integer.parseInt(st.nextToken());
 
            list[x][y] = 2;
        }
 
        st = new StringTokenizer(br.readLine());
        L = Integer.parseInt(st.nextToken());
        while (L-- > 0) {
            st = new StringTokenizer(br.readLine());
            x = Integer.parseInt(st.nextToken());
            char c = st.nextToken().charAt(0);
            ch[x] = c;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 2493 탑  (0) 2021.02.04
boj 6416 트리인가?  (0) 2021.02.04
boj 2346 풍선 터뜨리기  (0) 2021.02.02
boj 5397 키로거  (0) 2021.02.02
boj 10866 덱  (0) 2021.02.02

www.acmicpc.net/problem/9202

 

9202번: Boggle

각각의 Boggle에 대해, 얻을 수 있는 최대 점수, 가장 긴 단어, 찾은 단어의 개수를 출력한다. 한 Boggle에서 같은 단어를 여러 번 찾은 경우에는 한 번만 찾은 것으로 센다. 가장 긴 단어가 여러 개

www.acmicpc.net

먼저 사전에 들어갈 N개의 단어가 주어지고, 4*4크기의 그리드가 주어집니다.

이 그리드에서 가로, 세로, 대각선으로 인접한 글자로 사전의 단어를 몇 개 만들 수 있는지 찾는 문제입니다.

출력해야 할 것은 게임에서 얻을 수 있는 최대 점수, 찾은 단어 중 가장 긴 단어, 찾은 단어의 갯수 입니다.

 

저는 사전의 단어를 dfs로 하나씩 확인하였습니다.

(1,1) -> (1,2) -> (1,1)와 같은 중복방문이 없어야하므로 visit를 이용해 방문체크를 하였고,

한 인덱스에서 단어찾기에 실패하면 그 인덱스의 방문처리는 false로 하여 재방문 할 수 있게 하였습니다.

 

단어 찾는데 성공하면 가장 긴 단어를 최신화하고, 단어 길이에 맞는 점수 증가와 단어 갯수를 1 증가시킵니다.

그리고 같은 단어를 여러번 찾을 필요가 없으므로 찾았다는 표시로 chk = true를 해서 다음 단어로 바로 넘어갑니다.

 

가장 긴 단어를 출력할 때는 길이가 긴 것, 길이가 같으면 사전 순으로 앞서는 것을 출력합니다.

 

 

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
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 int direct[][] = { { 01 }, { 11 }, { 10 }, { 1-1 }, { 0-1 }, { -1-1 }, { -10 }, { -11 } };
    static int score[] = { 0001123511 };
    static String dict[];
    static char list[][];
    static boolean visit[][], chk;
    static String maxlength = "";
    static int N, M, maxscore, ans;
 
    static void dfs(int k, int idx, int x, int y) {
        if (idx + 1 == dict[k].length()) {
            if (maxlength == "")
                maxlength = dict[k];
            else {
                if (maxlength.length() < dict[k].length())
                    maxlength = dict[k];
                else if (maxlength.length() == dict[k].length()) {
                    if (maxlength.compareTo(dict[k]) > 0)
                        maxlength = dict[k];
                }
            }
 
            maxscore += score[idx + 1];
            chk = true;
            return;
        }
 
        visit[x][y] = true;
 
        for (int i = 0; i < 8; i++) {
            int nx = x + direct[i][0];
            int ny = y + direct[i][1];
 
            if (nx < 0 || ny < 0 || nx >= 4 || ny >= 4)
                continue;
            if (visit[nx][ny] || list[nx][ny] != dict[k].charAt(idx + 1))
                continue;
 
            dfs(k, idx + 1, nx, ny);
            if (chk)
                return;
 
            visit[nx][ny] = false;
        }
    }
 
    static void func() {
        for (int k = 0; k < N; k++) {
            chk = false;
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (list[i][j] == dict[k].charAt(0)) {
                        visit = new boolean[4][4];
                        dfs(k, 0, i, j);
                        if (chk) {
                            ans++;
                            break;
                        }
                    }
                }
 
                if (chk)
                    break;
            }
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        dict = new String[N];
        list = new char[4][4];
 
        for (int i = 0; i < N; i++) {
            dict[i] = br.readLine();
        }
        br.readLine();
 
        st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < 4; j++) {
                st = new StringTokenizer(br.readLine());
                list[j] = st.nextToken().toCharArray();
            }
 
            func();
            sb.append(maxscore + " " + maxlength + " " + ans + "\n");
            maxscore = 0;
            maxlength = "";
            ans = 0;
 
            if (i == M - 1)
                break;
            br.readLine();
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        System.out.println(sb.toString());
    }
}
cs

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

boj 16926 배열 돌리기 1  (0) 2021.02.10
boj 1068 트리  (0) 2021.02.09
boj 15666 N과 M (12)  (0) 2021.01.31
boj 15665 N과 M (11)  (0) 2021.01.30
boj 15664 N과 M (10)  (0) 2021.01.30

www.acmicpc.net/problem/2346

 

2346번: 풍선 터뜨리기

첫째 줄에 자연수 N(1≤N≤1,000)이 주어진다. 다음 줄에는 차례로 각 풍선 안의 종이에 적혀 있는 수가 주어진다. 편의상 0은 적혀있지 않다고 가정하자.

www.acmicpc.net

list의 첫번째 풍선을 터뜨리고 안에 적혀있는 수에 맞게 이동하여 다음 풍선을 터뜨리고, 최종적으로 풍선을 터뜨리는 순서를 구하는 문제입니다.

 

저는 덱을 이용하였습니다. 풍선을 터뜨릴 위치는 무조건 덱의 맨 앞입니다.

그러면 다음 위치를 찾아서 맨 앞으로 가져다 놓아야합니다.

 

풍선에 적혀있는 수가 양수면 오른쪽으로 이동하는 것인데

덱의 맨 앞의 숫자를 맨 뒤로 보내는 것으로 해결할 수 있습니다.

하지만 양수가 적혀있는 풍선을 터뜨리면 이미 한칸은 오른쪽으로 이동한 것이기 때문에 숫자-1만큼만 이동시킵니다.

 

풍선에 적혀있는 수가 음수면 왼쪽으로 이동합니다.

덱의 맨 뒤의 숫자를 맨 앞으로 보내는 것으로 해결할 수 있습니다.

 

마지막 풍선까지 터뜨리고 덱이 비어있으면 break를 해주고 답을 출력합니다.

 

 

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
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 StringBuffer sb = new StringBuffer();
    static Deque<int[]> dq = new ArrayDeque<>();
    static int N;
 
    static void func() {
        for (int i = 0; i < N; i++) {
            int next = dq.peekFirst()[0];
            sb.append(dq.peekFirst()[1+ " ");
            dq.removeFirst();
 
            if (dq.isEmpty())
                break;
            
            if (next > 0) {
                next--;
                while (next-- > 0) {
                    dq.addLast(dq.peekFirst());
                    dq.removeFirst();
                }
            } else {
                while (next++ < 0) {
                    dq.addFirst(dq.peekLast());
                    dq.removeLast();
                }
            }
        }
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= N; i++) {
            dq.addLast(new int[] { Integer.parseInt(st.nextToken()), i });
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 6416 트리인가?  (0) 2021.02.04
boj 3190 뱀  (0) 2021.02.02
boj 5397 키로거  (0) 2021.02.02
boj 10866 덱  (0) 2021.02.02
boj 11000 강의실 배정  (0) 2021.02.01

+ Recent posts