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

www.acmicpc.net/problem/2331

 

2331번: 반복수열

첫째 줄에 반복되는 부분을 제외했을 때, 수열에 남게 되는 수들의 개수를 출력한다.

www.acmicpc.net

D[1] = A

D[n] = D[n - 1]의 각 자리의 숫자를 M번 곱한 수(각 자리마다 ^M)들의 합입니다.

 

전 재귀를 돌려가면서 현재 숫자와 수열의 갯수를 유지하였습니다.

일의자리부터 pow(tmp, M)한 값을 next에 차례대로 더해줍니다.

next가 set에 있는 값이면 cyclestart에 next를 넣어주고 리턴합니다.

(예외처리로 D[n] = D[n - 1] 즉, 자신 다음이 자신일 경우가 있어 처리해주었습니다.)

 

재귀를 빠져나오면서 num == cyclestart이면 ans에 cnt - 1을 넣어주어 출력하였습니다.

 

 

[C++]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <set>
#include <cmath>
using namespace std;
 
set<int> s;
int N, M, cyclestart, ans;
 
void func(int num, int cnt) {
    s.insert(num);
 
    int n = num;
    int next = 0;
    while (1) {
        int tmp = n % 10;
        tmp = pow(tmp, M);
        next += tmp;
        n /= 10;
        if (!n) break;
    }
 
    if (s.find(next) != s.end()) {
        cyclestart = next;
        if (cyclestart == num) ans = cnt - 1;
        return;
    }
 
    func(next, cnt + 1);
    if (num == cyclestart)
        ans = cnt - 1;
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    cin >> N >> M;
    func(N, 1);
    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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Set<Integer> s = new HashSet<>();
    static int N, M, cyclestart, ans;
 
    static void func(int num, int cnt) {
        s.add(num);
 
        int next = 0;
        int n = num;
        while (true) {
            next += Math.pow(n % 10, M);
            n /= 10;
            if (n == 0)
                break;
        }
 
        if (s.contains(next)) {
            if (next == num)
                ans = cnt - 1;
            cyclestart = next;
            return;
        }
 
        func(next, cnt + 1);
        if (cyclestart == num)
            ans = cnt - 1;
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(N, 1);
        System.out.println(ans);
    }
}
cs

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

boj 10163 색종이  (0) 2021.02.24
boj 20055 컨베이어 벨트 위의 로봇  (0) 2021.02.23
boj 10157 자리배정  (0) 2021.02.17
boj 16918 봄버맨  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10

www.acmicpc.net/problem/10157

 

10157번: 자리배정

첫 줄에는 공연장의 격자 크기를 나타내는 정수 C와 R이 하나의 공백을 사이에 두고 차례대로 주어진다. 두 값의 범위는 5 ≤ C, R ≤ 1,000이다. 그 다음 줄에는 어떤 관객의 대기번호 K가 주어진다.

www.acmicpc.net

문제의 그림은 이렇게 나와있지만

 

저는 편의를 위해 이렇게 옆으로 회전시켜서 구현하였습니다.

 

그 다음 (x, y) = (0, 0)으로 초기값을 잡고 시뮬레이션을 돌렸습니다.

진행방향은 오른쪽 -> 아래쪽 -> 왼쪽 -> 위쪽 순서입니다.

(nx ,ny)이 맵 밖으로 나가거나 방문한 좌표면 방향을 바꿔주고 다시 돌려줍니다.

이 과정에서 번호가 K에 도달하면 좌표를 출력해줍니다.

 

좌석은 N * M개 있으므로 만약 K가 N * M보다 크면 0을 출력하고 그냥 리턴시켜줍니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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 boolean visit[][];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int N, M, K;
 
    static void func() {
        if (K > N * M) {
            System.out.println(0);
            return;
        }
 
        int x = 0;
        int y = 0;
        int idx = 0;
        for (int k = 1; k <= N * M; k++) {
            visit[x][y] = true;
            if (k == K) {
                System.out.println((x + 1+ " " + (y + 1));
                return;
            }
 
            int nx = x + direct[idx][0];
            int ny = y + direct[idx][1];
            if (nx < 0 || ny < 0 || nx >= N || ny >= M || visit[nx][ny]) {
                idx = (idx + 1) % 4;
                nx = x + direct[idx][0];
                ny = y + direct[idx][1];
            }
 
            x = nx;
            y = ny;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());
        K = Integer.parseInt(st.nextToken());
        visit = new boolean[N][M];
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 20055 컨베이어 벨트 위의 로봇  (0) 2021.02.23
boj 2331 반복수열  (0) 2021.02.23
boj 16918 봄버맨  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10
boj 1914 하노이 탑  (0) 2021.02.07

www.acmicpc.net/problem/16918

 

16918번: 봄버맨

첫째 줄에 R, C, N (1 ≤ R, C, N ≤ 200)이 주어진다. 둘째 줄부터 R개의 줄에 격자판의 초기 상태가 주어진다. 빈 칸은 '.'로, 폭탄은 'O'로 주어진다.

www.acmicpc.net

1. 가장 처음에 봄버맨은 일부 칸에 폭탄을 설치합니다. (입력으로 주어집니다.)

2. 1초 후에 봄버맨은 아무것도 하지않습니다.

3. 다음 1초 후에 폭탄이 설치되어 있지 않은 모든 칸에 폭탄을 동시에 설치합니다.

4. 다음 1초 후에 3초전에 설치했던 폭탄이 터집니다. 이때 바로 옆 공간의 폭탄도 터집니다.

5. 이후 3과 4를 반복합니다.

 

저는 폭탄을 나타내는 char형 배열과 시간(카운트)를 나타내는 int형 배열을 사용하였습니다.

3번 4번 과정을 반복하고, 처음 1번과정은 입력으로 주어진 후 1초동안은 아무것도 하지않기때문에

K를 1빼주고 처음 입력으로 주어진 폭탄들의 시간은 2초로 해줍니다.

 

그리고 반복문은 2초부터 돌려줍니다.

폭탄은 짝수 초에 터지고, 홀수 초에 놓아지기때문에 홀, 짝으로 나누어 구현하였습니다.

 

폭탄을 놓을 때는 시간이 0인 모든 공간에 놓아주었고, 시간이 0이 아니면 1 감소시켰습니다.

폭탄을 터뜨릴 때는 터져야할 모든 폭탄을 덱에 넣고, bfs방식으로 인접한 폭탄들을 함께 터뜨렸습니다.

마지막으로 K초가 지난 후의 격자판 상태를 출력해주시면 됩니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Deque<int[]> dq = new ArrayDeque<>();
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static char list[][];
    static int time[][];
    static int N, M, K;
 
    static void print() {
        StringBuffer sb = new StringBuffer();
        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 bfs() {
        while (!dq.isEmpty()) {
            int x = dq.peekFirst()[0];
            int y = dq.pollFirst()[1];
            
            for (int k = 0; k < 4; k++) {
                int nx = x + direct[k][0];
                int ny = y + direct[k][1];
 
                if (nx < 0 || ny < 0 || nx >= N || ny >= M)
                    continue;
                time[nx][ny] = 0;
                list[nx][ny] = '.';
            }
        }
    }
 
    static void func() {
        for (int t = 1; t <= K; t++) {
            if (t % 2 != 0) {
                for (int i = 0; i < N; i++) {
                    for (int j = 0; j < M; j++) {
                        if (time[i][j] == 0) {
                            list[i][j] = 'O';
                            time[i][j] = 3;
                        } else
                            time[i][j]--;
                    }
                }
            } else {
                for (int i = 0; i < N; i++) {
                    for (int j = 0; j < M; j++) {
                        if (time[i][j] == 0)
                            continue;
                        time[i][j]--;
                        if (time[i][j] == 0) {
                            list[i][j] = '.';
                            dq.addLast(new int[] { i, j });
                        }
                    }
                }
 
                bfs();
            }
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken()) - 1;
        time = new int[N][M];
        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] == 'O') {
                    time[i][j] = 2;
                }
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

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

boj 2331 반복수열  (0) 2021.02.23
boj 10157 자리배정  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10
boj 1914 하노이 탑  (0) 2021.02.07
boj 11729 하노이 탑 이동 순서  (0) 2021.02.07

www.acmicpc.net/problem/16935

 

16935번: 배열 돌리기 3

크기가 N×M인 배열이 있을 때, 배열에 연산을 R번 적용하려고 한다. 연산은 총 6가지가 있다. 1번 연산은 배열을 상하 반전시키는 연산이다. 1 6 2 9 8 4 → 4 2 9 3 1 8 7 2 6 9 8 2 → 9 2 3 6 1 5 1 8 3 4 2 9 →

www.acmicpc.net

1. 배열을 상하반전 시킨다.

2. 배열을 좌우반전 시킨다.

3. 배열을 오른쪽으로 90도 회전시킨다.

4. 배열을 왼쪽으로 90도 회전시킨다.

5. 1번그룹 -> 2번그룹 / 2번그룹 -> 3번그룹 / 3번그룹 -> 4번그룹 / 4번그룹 -> 1번그룹으로 각각 이동시킨다.

6. 1번그룹 -> 4번그룹 / 4번그룹 -> 3번그룹 / 3번그룹 -> 2번그룹 / 2번그룹 -> 1번그룹으로 각각 이동시킨다.

 

1, 2번은 양끝의 숫자를 바꿔주기만 하면 됩니다.

3, 4번은 (N, M)크기의 배열을 회전시키면 (M, N)크기의 배열로 바뀝니다. 인덱스를 조절하여 해결합니다.

 

5, 6번은 위의 그림처럼 구간을

1번 - (0, 0) ~ (N / 2 - 1, M / 2 - 1)

2번 - (0, N / 2) ~ (N / 2 - 1, M - 1)

3번 - (N / 2, M / 2) ~ (N - 1, M - 1)

4번 - (N / 2, 0) ~ (N - 1, M / 2 - 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
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[][], calc[];
    static int N, M, R;
 
    static void cal1() {
        for (int i = 0, k = N - 1; i < N / 2; i++, k--) {
            for (int j = 0; j < M; j++) {
                int tmp = list[i][j];
                list[i][j] = list[k][j];
                list[k][j] = tmp;
            }
        }
    }
 
    static void cal2() {
        for (int i = 0; i < N; i++) {
            for (int j = 0, k = M - 1; j < M / 2; j++, k--) {
                int tmp = list[i][j];
                list[i][j] = list[i][k];
                list[i][k] = tmp;
            }
        }
    }
 
    static void cal3() {
        int newlist[][] = new int[M][N];
        int x = 0;
        int y = N - 1;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                newlist[x][y] = list[i][j];
                x++;
            }
            x = 0;
            y--;
        }
        int tmp = N;
        N = M;
        M = tmp;
 
        list = newlist;
    }
 
    static void cal4() {
        int newlist[][] = new int[M][N];
        int x = M - 1;
        int y = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                newlist[x][y] = list[i][j];
                x--;
            }
            x = M - 1;
            y++;
        }
        int tmp = N;
        N = M;
        M = tmp;
 
        list = newlist;
    }
 
    static void cal5() {
        int x1 = 0, y1 = 0;
        int x2 = 0, y2 = M / 2;
        int x3 = N / 2, y3 = M / 2;
        int x4 = N / 2, y4 = 0;
        for (int i = 0; i < N / 2; i++) {
            for (int j = 0; j < M / 2; j++) {
                int tmp = list[x1][y1];
                list[x1][y1] = list[x4][y4];
                list[x4][y4] = list[x3][y3];
                list[x3][y3] = list[x2][y2];
                list[x2][y2] = tmp;
 
                y1++;
                y2++;
                y3++;
                y4++;
            }
            y1 = 0;
            y2 = M / 2;
            y3 = M / 2;
            y4 = 0;
            x1++;
            x2++;
            x3++;
            x4++;
        }
    }
 
    static void cal6() {
        int x1 = 0, y1 = 0;
        int x2 = 0, y2 = M / 2;
        int x3 = N / 2, y3 = M / 2;
        int x4 = N / 2, y4 = 0;
        for (int i = 0; i < N / 2; i++) {
            for (int j = 0; j < M / 2; j++) {
                int tmp = list[x1][y1];
                list[x1][y1] = list[x2][y2];
                list[x2][y2] = list[x3][y3];
                list[x3][y3] = list[x4][y4];
                list[x4][y4] = tmp;
 
                y1++;
                y2++;
                y3++;
                y4++;
            }
            y1 = 0;
            y2 = M / 2;
            y3 = M / 2;
            y4 = 0;
            x1++;
            x2++;
            x3++;
            x4++;
        }
    }
 
    static void func() {
        for (int i = 0; i < R; i++) {
            if (calc[i] == 1)
                cal1();
            else if (calc[i] == 2)
                cal2();
            else if (calc[i] == 3)
                cal3();
            else if (calc[i] == 4)
                cal4();
            else if (calc[i] == 5)
                cal5();
            else
                cal6();
        }
    }
 
    static void print() {
        StringBuffer sb = new StringBuffer();
        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 input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        R = Integer.parseInt(st.nextToken());
        list = new int[N][M];
        calc = new int[R];
        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());
            }
        }
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < R; i++) {
            calc[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

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

boj 10157 자리배정  (0) 2021.02.17
boj 16918 봄버맨  (0) 2021.02.17
boj 1914 하노이 탑  (0) 2021.02.07
boj 11729 하노이 탑 이동 순서  (0) 2021.02.07
boj 1244 스위치 켜고 끄기  (0) 2021.02.01

www.acmicpc.net/problem/1914

 

1914번: 하노이 탑

세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로

www.acmicpc.net

emoney96.tistory.com/102

 

boj 11729 하노이 탑 이동 순서

www.acmicpc.net/problem/11729 11729번: 하노이 탑 이동 순서 세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이

emoney96.tistory.com

이 문제랑 같은 문제입니다.

이동 순서는 위의 문제와 동일하게 해주시면 됩니다.

 

하나 다른점은 N이 최대 100이며, N>20인 경우에는 횟수만 출력합니다.

2^100 - 1 = 1267650600228229401496703205375 이므로 long의 범위도 초과합니다.

그래서 자바의 BigInteger를 사용합니다.

BigInteger에 pow라는 지수메소드가 있어서 2^N을 구할 수 있고, subtract 메소드로 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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
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 BigInteger ans = new BigInteger("2");
    static int N;
 
    static void func(int n, int a, int b, int c) {
        if (n < 1)
            return;
 
        func(n - 1, a, c, b);
        sb.append(a + " " + c + "\n");
        func(n - 1, b, a, c);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
 
        ans = ans.pow(N).subtract(new BigInteger("1"));
    }
 
    public static void main(String[] args) throws Exception {
        input();
        System.out.println(ans);
        if (N > 20) {
            return;
        }
        func(N, 123);
        System.out.println(sb.toString());
    }
}
cs

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

boj 16918 봄버맨  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10
boj 11729 하노이 탑 이동 순서  (0) 2021.02.07
boj 1244 스위치 켜고 끄기  (0) 2021.02.01
boj 20127 Y-수열  (0) 2021.01.22

www.acmicpc.net/problem/11729

 

11729번: 하노이 탑 이동 순서

세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로

www.acmicpc.net

하노이탑 이동 횟수와 순서를 출력하는 문제입니다.

 

하노이탑은 3개의 기둥이 있고, 한 기둥에 원판들이 작은 것이 위에 있고 순서대로 밑으로 쌓여있습니다.

한 번에 하나의 원판만 옮길 수 있고, 큰 원판이 작은 원판 위에 있으면 안됩니다.

 

일단 원판이 n개 일 때, 이동 횟수는 2^n - 1개입니다.

비트연산을 이용하면 빠르게 구할 수 있습니다.

 

그리고, 재귀를 통해 순서를 출력해주시면 됩니다.

저는 "func(n, a, b, c) : n개의 원판이 a에서 c로 이동하는 경우" 이렇게 함수를 선언하였습니다.

그 다음 n - 1개를 a에서 b로 옮기고, 나머지 1개를 a에서 c로 옮기고, n - 1개를 b에서 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
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 N;
 
    static void func(int n, int a, int b, int c) {
        if (n < 1)
            return;
        func(n - 1, a, c, b);
        sb.append(a + " " + c + "\n");
        func(n - 1, b, a, c);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
 
        sb.append((2 << (N - 1)) - 1 + "\n");
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(N, 123);
        System.out.println(sb.toString());
    }
}
cs

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

boj 16918 봄버맨  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10
boj 1914 하노이 탑  (0) 2021.02.07
boj 1244 스위치 켜고 끄기  (0) 2021.02.01
boj 20127 Y-수열  (0) 2021.01.22

www.acmicpc.net/problem/1244

 

1244번: 스위치 켜고 끄기

첫째 줄에는 스위치 개수가 주어진다. 스위치 개수는 100 이하인 양의 정수이다. 둘째 줄에는 각 스위치의 상태가 주어진다. 켜져 있으면 1, 꺼져있으면 0이라고 표시하고 사이에 빈칸이 하나씩

www.acmicpc.net

1(남학생)일 경우 받은 번호의 모든 배수 번호의 스위치 상태를 바꿉니다.

2(여학생)일 경우 받은 번호를 중점으로 좌우 상태가 같은 스위치 상태를 바꿉니다.

 

1의 경우에는 x부터 N까지 x를 더하면서 상태를 변경하였고,

2의 경우에는 인덱스 두개를 사용하여 비교해가면서 상태를 변경하였습니다.

 

출력은 한 줄에 20개씩 해야합니다.

저는 문제를 제대로 안읽어서 WA를 받았습니다 ㅠㅠ

 

 

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
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[], student[][];
    static int N, M;
 
    static void solve1(int x) {
        for (int i = x; i <= N; i += x) {
            list[i] = 1 - list[i];
        }
    }
 
    static void solve2(int x) {
        int l = x - 1;
        int r = x + 1;
        list[x] = 1 - list[x];
        while (l >= 1 && r <= N) {
            if (list[l] == list[r]) {
                list[l] = 1 - list[l];
                list[r] = 1 - list[r];
                l--;
                r++;
            } else
                break;
        }
    }
 
    static void func() {
        for (int i = 0; i < M; i++) {
            int type = student[i][0];
            int x = student[i][1];
 
            if (type == 1)
                solve1(x);
            else
                solve2(x);
        }
    }
 
    static void print() {
        for (int i = 1; i <= N; i++) {
            System.out.print(list[i] + " ");
            if (i % 20 == 0)
                System.out.println();
        }
        System.out.println();
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N + 1];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
 
        st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        student = new int[M][2];
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            student[i][0= Integer.parseInt(st.nextToken());
            student[i][1= Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

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

boj 16918 봄버맨  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10
boj 1914 하노이 탑  (0) 2021.02.07
boj 11729 하노이 탑 이동 순서  (0) 2021.02.07
boj 20127 Y-수열  (0) 2021.01.22

 

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

 

20127번: Y-수열

N개의 정수로 이루어진 수열 a1, ... , aN이 있다. 택희는 해당 수열이 증가수열 혹은 감소수열이 되게 만들고 싶다. 증가수열은 모든 i(1 ≤ i < N)에 대해서 ai ≤ ai+1을 만족하는 수열이고, 감소수열

www.acmicpc.net

 

맨 앞의 k개의 원소를 맨 뒤로 옮겨서 증가 또는 감소수열을 만들어야하는데 여기서 k의 최솟값을 출력해야합니다.

반례로 만들 수 없다면 -1을 출력합니다.

 

우선 맨 앞의 연속된 k개의 원소를 한 번만 움직이는거기 때문에 주어진 배열 list를 구간별로 나누면 2개의 구간이 나옵니다.

 

(편의를 위해 앞에서부터 구간1, 구간2로 하겠습니다.)

구간1의 맨 앞의 숫자가 구간2의 뒤로 가기때문에

 

증가수열을 만들 때는

구간1의 맨 앞의 숫자가 구간2의 맨 뒤의 숫자보다 크거나 같아야하고,

감소수열을 만들 때는

구간1의 맨 앞의 숫자가 구간2의 맨 뒤의 숫자보다 작거나 같아야합니다.

증가, 감소 수열을 만들 때 나온 각각의 k를 비교하여 작은 수를 출력하면 됩니다.

 

예외처리로 구간이 1개 나온다면 그냥 증가 또는 감소수열이 주어진 것이므로 0을 출력하면 되고,

2개보다 많이 나온다면 만들 수 없는 것이므로 -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
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 Queue<ArrayList<Integer>> inq = new LinkedList<>();
    static Queue<ArrayList<Integer>> deq = new LinkedList<>();
    static int N, inans, deans;
    static int list[] = new int[1000001];
 
    static void func() {
        ArrayList<Integer> newlist = new ArrayList<>();
        newlist.add(list[0]);
        for (int i = 1; i < N; i++) {
            if (list[i] >= list[i - 1])
                newlist.add(list[i]);
            else {
                inq.add(newlist);
                newlist = new ArrayList<>();
                newlist.add(list[i]);
            }
        }
        inq.add(newlist);
        if (inq.size() > 2)
            inans = -1;
        else if (inq.size() == 1)
            inans = 0;
        else {
            int size = inq.peek().size();
            int l = inq.peek().get(0);
            inq.remove();
            int r = inq.peek().get(inq.peek().size() - 1);
 
            if (l >= r)
                inans = size;
            else
                inans = -1;
        }
 
        newlist = new ArrayList<>();
        newlist.add(list[0]);
        for (int i = 1; i < N; i++) {
            if (list[i] <= list[i - 1])
                newlist.add(list[i]);
            else {
                deq.add(newlist);
                newlist = new ArrayList<>();
                newlist.add(list[i]);
            }
        }
        deq.add(newlist);
 
        if (deq.size() > 2)
            deans = -1;
        else if (deq.size() == 1)
            deans = 0;
        else {
            int size = deq.peek().size();
            int l = deq.peek().get(0);
            deq.remove();
            int r = deq.peek().get(deq.peek().size() - 1);
 
            if (r >= l)
                deans = size;
            else
                deans = -1;
        }
    }
 
    static void solve() {
        if (inans == -1 && deans == -1)
            System.out.println(-1);
        else if (inans == -1)
            System.out.println(deans);
        else if (deans == -1)
            System.out.println(inans);
        else
            System.out.println(Math.min(inans, deans));
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = 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();
        solve();
    }
}
cs

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

boj 16918 봄버맨  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10
boj 1914 하노이 탑  (0) 2021.02.07
boj 11729 하노이 탑 이동 순서  (0) 2021.02.07
boj 1244 스위치 켜고 끄기  (0) 2021.02.01

+ Recent posts