www.acmicpc.net/problem/20055

 

20055번: 컨베이어 벨트 위의 로봇

길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부

www.acmicpc.net

1번 칸 - 로봇이 올라가는 위치

N번 칸 - 로봇이 내려가는 위치

 

로봇은 무조건 1번 칸에만 놓아야하며, 컨베이어 벨트에서의 이동은 가능합니다.

 

컨베이어 벨트를 이용하여 로봇들을 옮기는 과정은

1. 벨트가 한 칸 회전합니다.

2. 벨트에 로봇이 올라가있으면 회전하는 방향으로 한 칸 이동할 수 있으면 이동합니다.

3. 로봇이 이동한 칸의 내구도가 1 감소합니다.

4. 올라가는 위치(1번 칸)에 로봇이 없고, 내구도가 0이 아니면 로봇을 하나 올립니다.

5. 로봇이 올라가면서 올라가는 위치(1번 칸)의 내구도가 1 감소합니다.

6. 내구도가 0인 칸의 갯수가 K개 이상이면 과정을 종료, 아니면 1번부터 다시 수행합니다.

7. 과정이 종료되면 t를 출력합니다.

 

두 가지 방법으로 해결하였는데

첫 번째는 벡터(C++)와 연결리스트(Java)를 이용하여 컨베이어 벨트를 직접 옮긴 후에 로봇 이동

두 번째는 올라가는 위치와 내려가는 위치를 인덱스로만 유지하고 로봇 이동

당연히 두 번째방법이 훨씬 효율적이었습니다. 업로드는 두 가지 모두 업로드하겠습니다.

 

벡터와 연결리스트를 이용한 방법입니다.

저는 벡터를 사용하여 칸의 내구도, 로봇의 존재여부를 저장하였습니다.

컨베이어 벨트가 이동하는 것은 벡터의 마지막 요소를 begin()에 넣어주었고,

N ~ 1번 칸까지 역순으로 컨베이어 벨트 위에있는 모든 로봇을 이동시켜주었습니다.

그 다음 1번 칸에 로봇을 놓았고 이 과정에서 칸의 내구도가 0이되면 ans를 1증가하였습니다.

반복문 마지막에 ans가 K 이상인지 확인하였고, 이상이면 t를 출력하고 리턴, 아니면 계속 반복문을 돌려주었습니다.

 

그 다음은 인덱스를 유지한 방법입니다.

l = 1

r = N

으로 시작하고 컨베이어 이동 시마다 1씩 빼줍니다. (0이되면 2 * N으로)

그 다음 r부터 l까지 역순으로 컨베이어 벨트 위에있는 모든 로봇을 이동시켜줍니다.

그 다음 l번 칸에 로봇을 놓고 내구도를 감소시킵니다.

이 과정에서 내구도가 0이되면 ans++, ans가 K 이상이면 t를 출력합니다.

 

Java LinkedList를 이용한 방법
Java 인덱스를 이동한 방법

 

로직은 같으나 컨베이어 이동을 시뮬레이션으로 직접 이동시키냐, 인덱스만 이동시키냐에 따라 시간 차이가 크게남을 확인하였습니다.

 

 

[벡터 이용한 풀이]

[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
#include <iostream>
#include <vector>
using namespace std;
 
vector<pair<intint> > list;
int N, K, ans;
 
void func() {
    for (int t = 1; ; t++) {
        list.insert(list.begin(), list[2 * N - 1]);
        list.pop_back();
 
        for (int i = N - 1; i >= 0; i--) {
            if (i == N - 1) {
                list[i].second = 0;
                continue;
            }
            if (!list[i].second) continue;
            if (!list[i + 1].first || list[i + 1].second) continue;
 
            if (i + 1 != N - 1) list[i + 1].second = 1;
            list[i].second = 0;
            list[i + 1].first--;
 
            if (!list[i + 1].first) ans++;
        }
 
        if (list[0].first) {
            list[0].second = 1;
            list[0].first--;
            if (!list[0].first) ans++;
        }
 
        if (ans >= K) {
            cout << t << '\n';
            break;
        }
    }
}
 
void input() {
    int x;
    cin >> N >> K;
    for (int i = 1; i <= 2 * N; i++) {
        cin >> x;
        list.push_back({ x, 0 });
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static LinkedList<int[]> list = new LinkedList<>();
    static int N, K, ans;
 
    static void func() {
        for (int t = 1;; t++) {
            list.addFirst(list.pollLast());
 
            for (int i = N - 1; i >= 0; i--) {
                if (i == N - 1) {
                    list.get(i)[1= 0;
                    continue;
                }
                if (list.get(i)[1== 0)
                    continue;
                if (list.get(i + 1)[0== 0 || list.get(i + 1)[1!= 0)
                    continue;
 
                if (i + 1 != N - 1)
                    list.get(i + 1)[1= 1;
                list.get(i)[1= 0;
                list.get(i + 1)[0]--;
                if (list.get(i + 1)[0== 0)
                    ans++;
            }
 
            if (list.get(0)[0> 0) {
                list.get(0)[0]--;
                list.get(0)[1= 1;
                if (list.get(0)[0== 0)
                    ans++;
            }
 
            if (ans >= K) {
                System.out.println(t);
                break;
            }
        }
    }
 
    static void input() throws Exception {
        int x;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < 2 * N; i++) {
            x = Integer.parseInt(st.nextToken());
            list.addLast(new int[] { x, 0 });
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

 

[인덱스 유지]

 

[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
#include <iostream>
using namespace std;
 
pair<intint> list[201];
int N, K, ans;
 
void func() {
    int l = 1;
    int r = N;
    for (int t = 1; ; t++) {
        l--;
        r--;
        if (!l) l = 2 * N;
        if (!r) r = 2 * N;
 
        for (int i = r; ; i--) {
            if (!i) i = 2 * N;
            if (i == r) {
                list[i].second = 0;
                continue;
            }
            int next = i + 1;
            if (next == 2 * N + 1) next = 1;
            
            if (!list[i].second) {
                if (i == l) break;
                continue;
            }
            if (!list[next].first || list[next].second) {
                if (i == l) break;
                continue;
            }
 
            if (next != r) list[next].second = 1;
            list[i].second = 0;
            list[next].first--;
 
            if (!list[next].first) ans++;
            
            if (i == l) break;
        }
 
        if (list[l].first) {
            list[l].second = 1;
            list[l].first--;
            if (!list[l].first) ans++;
        }
 
        if (ans >= K) {
            cout << t << '\n';
            break;
        }
    }
}
 
void input() {
    int x;
    cin >> N >> K;
    for (int i = 1; i <= 2 * N; i++) {
        cin >> list[i].first;
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    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
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[][];
    static int N, K, ans;
 
    static void func() {
        int l = 1;
        int r = N;
        for (int t = 1;; t++) {
 
            l--;
            r--;
            if (l == 0)
                l = 2 * N;
            if (r == 0)
                r = 2 * N;
 
            for (int i = r;; i--) {
                if (i == 0)
                    i = 2 * N;
                if (i == r) {
                    list[i][1= 0;
                    continue;
                }
                int next = i + 1;
                if (next == 2 * N + 1)
                    next = 1;
 
                if (list[i][1== 0) {
                    if (i == l)
                        break;
                    continue;
                }
                if (list[next][0== 0 || list[next][1== 1) {
                    if (i == l)
                        break;
                    continue;
                }
 
                if (next != r)
                    list[next][1= 1;
                list[i][1= 0;
                list[next][0]--;
 
                if (list[next][0== 0)
                    ans++;
 
                if (i == l)
                    break;
            }
 
            if (list[l][0> 0) {
                list[l][1= 1;
                list[l][0]--;
                if (list[l][0== 0)
                    ans++;
            }
 
            if (ans >= K) {
                System.out.println(t);
                break;
            }
        }
    }
 
    static void input() throws Exception {
        int x;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        list = new int[2 * N + 1][2];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= 2 * N; i++) {
            list[i][0= Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

 

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

boj 2116 주사위 쌓기  (0) 2021.02.25
boj 10163 색종이  (0) 2021.02.24
boj 2331 반복수열  (0) 2021.02.23
boj 10157 자리배정  (0) 2021.02.17
boj 16918 봄버맨  (0) 2021.02.17

+ Recent posts