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/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

www.acmicpc.net/problem/5397

 

5397번: 키로거

첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한줄로 이루어져 있고, 강산이가 입력한 순서대로 길이가 L인 문자열이 주어진다. (1 ≤ L의 길이 ≤ 1,000,000) 강산이가 백스페이

www.acmicpc.net

두 개의 덱을 이용하여 해결할 수 있습니다.

덱을 두 개 사용한 이유는 커서의 위치를 조정해주기 위함입니다.

저는 커서 좌, 우를 나누는 left와 right 덱을 선언하여 커서는 무조건 left를 가리키게 유지하였습니다.

 

우선 입력으로 '<', '>', '-' 그리고 나머지 문자가 주어집니다.

 

<이 주어지면 left에서 가장 뒤에있는 문자를 right 앞으로 push합니다. (left가 비어있으면 패스)

>이 주어지면 right에서 가장 앞에있는 문자를 left 뒤로 push합니다. (right가 비어있으면 패스)

-이 주어지면 left에서 가장 뒤에있는 문자를 pop합니다. (left가 비어있으면 패스)

나머지 문자가 주어지면 커서를 left로 유지해야하기 때문에 left 뒤로 push합니다.

 

이 과정이 끝나면 right에 있는 문자들을 앞에서부터 순서대로 left의 뒤로 차례대로 push하여 출력합니다.

 

 

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
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<Character> left, right;
    static char ch[];
 
    static void print() {
        while(!left.isEmpty()) {
            sb.append(left.peekFirst());
            left.removeFirst();
        }
        
        sb.append("\n");
    }
    
    static void func() {
        for (int i = 0; i < ch.length; i++) {
            if (ch[i] == '<') {
                if (left.isEmpty())
                    continue;
                right.addFirst(left.peekLast());
                left.removeLast();
            } else if (ch[i] == '>') {
                if (right.isEmpty())
                    continue;
                left.addLast(right.peekFirst());
                right.removeFirst();
            } else if (ch[i] == '-') {
                if (left.isEmpty())
                    continue;
                left.removeLast();
            } else
                left.addLast(ch[i]);
        }
        
        while(!right.isEmpty()) {
            left.addLast(right.peekFirst());
            right.removeFirst();
        }
    }
 
    static void input() throws Exception {
        left = new ArrayDeque<>();
        right = new ArrayDeque<>();
 
        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();
            print();
        }
        System.out.println(sb.toString());
    }
}
cs

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

boj 3190 뱀  (0) 2021.02.02
boj 2346 풍선 터뜨리기  (0) 2021.02.02
boj 10866 덱  (0) 2021.02.02
boj 11000 강의실 배정  (0) 2021.02.01
boj 1966 프린터 큐  (0) 2021.02.01

www.acmicpc.net/problem/10866

 

10866번: 덱

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지

www.acmicpc.net

덱의 기능들을 연습해볼 수 있는 기본적인 문제입니다.

 

덱은 push와 pop이 앞, 뒤로 모두 가능한 자료구조입니다.

 

push_front X : X를 덱 앞으로 push

push_back X : X를 덱 뒤로 push

pop_front : 덱의 가장 앞에있는 정수를 pop, 만약 덱이 비어있으면 -1 출력

pop_back : 덱의 가장 뒤에있는 정수를 pop, 만약 덱이 비어있으면 -1 출력

size : 덱의 크기 출력

empty : 덱이 비어있으면 1, 아니면 0을 출력

front : 덱의 가장 앞에있는 정수 출력, 만약 덱이 비어있으면 -1 출력

back : 덱의 가장 뒤에있는 정수 출력, 만약 덱이 비어있으면 -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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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<Integer> dq = new ArrayDeque<>();
    static int N;
 
    static void push_front(int x) {
        dq.addFirst(x);
    }
 
    static void push_back(int x) {
        dq.addLast(x);
    }
 
    static void pop_front() {
        if (dq.isEmpty()) {
            sb.append("-1\n");
            return;
        }
 
        sb.append(dq.peekFirst() + "\n");
        dq.removeFirst();
    }
 
    static void pop_back() {
        if (dq.isEmpty()) {
            sb.append("-1\n");
            return;
        }
 
        sb.append(dq.peekLast() + "\n");
        dq.removeLast();
    }
 
    static void size() {
        sb.append(dq.size() + "\n");
    }
 
    static void empty() {
        if (dq.isEmpty())
            sb.append("1\n");
        else
            sb.append("0\n");
    }
 
    static void front() {
        if (dq.isEmpty()) {
            sb.append("-1\n");
            return;
        }
 
        sb.append(dq.peekFirst() + "\n");
    }
 
    static void back() {
        if (dq.isEmpty()) {
            sb.append("-1\n");
            return;
        }
 
        sb.append(dq.peekLast() + "\n");
    }
 
    static void input() throws Exception {
        String type;
        int x;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
 
        while (N-- > 0) {
            st = new StringTokenizer(br.readLine());
            type = st.nextToken();
 
            if ("push_front".equals(type)) {
                x = Integer.parseInt(st.nextToken());
                push_front(x);
            } else if ("push_back".equals(type)) {
                x = Integer.parseInt(st.nextToken());
                push_back(x);
            } else if ("pop_front".equals(type))
                pop_front();
            else if ("pop_back".equals(type))
                pop_back();
            else if ("size".equals(type))
                size();
            else if ("empty".equals(type))
                empty();
            else if ("front".equals(type))
                front();
            else
                back();
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        System.out.println(sb.toString());
    }
}
cs

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

boj 2346 풍선 터뜨리기  (0) 2021.02.02
boj 5397 키로거  (0) 2021.02.02
boj 11000 강의실 배정  (0) 2021.02.01
boj 1966 프린터 큐  (0) 2021.02.01
boj 2164 카드2  (0) 2021.02.01

https://www.acmicpc.net/problem/11003

 

11003번: 최솟값 찾기

N개의 수 A1, A2, ..., AN과 L이 주어진다. Di = Ai-L+1 ~ Ai 중의 최솟값이라고 할 때, D에 저장된 수를 출력하는 프로그램을 작성하시오. 이때, i ≤ 0 인 Ai는 무시하고 D를 구해야 한다.

www.acmicpc.net

A[i-L+1]~A[i] 중 최솟값을 구하는 문제로 Deque를 이용하여 해결하였습니다.

 

큐가 비어있을 때는 바로 삽입하면 되고

반복문을 이용하여 삽입하려는 수가 큐의 뒤에있는 수보다 작을때마다 뒤의 값을 제거한 후에 삽입합니다.

 

만약 A[i-L+1]이 양수가 되면 큐의 앞에있는 수가 제거되었는지 확인하고 제거되지 않았으면 제거합니다.

그럼 큐의 맨앞에 있는 수가 최솟값이므로 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
58
59
60
61
62
63
64
65
66
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Deque;
import java.util.LinkedList;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[], ans[];
    static int N, L;
 
    static void func() {
        Deque<Integer> dq = new LinkedList<>();
        for (int i = 0; i < N; i++) {
            if (dq.isEmpty())
                dq.addLast(list[i]);
            else {
                while (true) {
                    if (dq.isEmpty())
                        break;
                    if (dq.peekLast() > list[i])
                        dq.removeLast();
                    else
                        break;
                }
 
                dq.addLast(list[i]);
            }
 
            if (L <= i) {
                if (dq.peek() == list[i - L])
                    dq.removeFirst();
            }
 
            ans[i] = dq.peek();
        }
    }
 
    static void print() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < N; i++) {
            sb.append(ans[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];
        ans = new int[N];
        L = Integer.parseInt(st.nextToken());
        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();
        print();
    }
}
cs

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

boj 5639 이진 검색 트리  (0) 2021.01.24
boj 1991 트리 순회  (0) 2021.01.22
boj 1517 버블 소트  (0) 2021.01.22
boj 2517 달리기  (0) 2021.01.22
boj 3425 고스택  (0) 2021.01.22

+ Recent posts