www.acmicpc.net/problem/17143

 

17143번: 낚시왕

낚시왕이 상어 낚시를 하는 곳은 크기가 R×C인 격자판으로 나타낼 수 있다. 격자판의 각 칸은 (r, c)로 나타낼 수 있다. r은 행, c는 열이고, (R, C)는 아래 그림에서 가장 오른쪽 아래에 있는 칸이다.

www.acmicpc.net

낚시왕은 1번 열부터 N번 열까지 1초에 한칸씩 움직이며 차례대로 낚시를 합니다.

1초동안 일어나는 일은

1. 낚시왕이 오른쪽으로 한 칸 이동합니다.

2. 낚시왕이 있는 열에 있는 상어 중에서 땅과 제일 가까운 상어를 잡습니다.

3. 상어가 이동합니다.

 

상어에 대한 정보는 좌표(x, y), 속력(s), 이동 방향(d), 크기(z)가 주어지며, 이동 방향에 맞춰서 속력만큼 이동합니다.

이동 중에 맵 밖으로 나가려고 하는 경우에는 방향을 반대로 바꿔준 후에 그대로 이동합니다.

 

상어가 이동을 마쳤을 때 같은 칸에 여러마리의 상어가 있을 수 있는데 이 경우에는 크기가 가장 큰 상어만 살아남습니다.

 

이 조건들을 모두 고려하여 시뮬레이션을 돌렸을 때 낚시왕이 잡은 상어의 크기 합을 구하는 문제입니다.

 

 

저는 두가지 방법으로 해결해보았습니다.

1. 배열의 모든 칸을 클래스화해서 관리하는 방법

2. 배열에는 상어의 번호만 유지하는 방법

 

먼저 첫 번째 방법입니다.

저는 모든 칸을 클래스화해서 관리하였습니다. (속력, 방향, 크기)

상어가 없는 칸은 (0, 0, 0)이 채워져있을 것이고, 상어가 있는 칸은 (speed, d, size)가 채워져 있습니다.

 

먼저 낚시왕이 상어를 잡고, 상어를 이동시켜줍니다.

이동을 완료한 상어들이 같은 좌표에 있으면 제거를 해야하기 때문에 상어들의 새로운 위치를 구별해주기 위한 새로운 배열(tmp)을 사용하였습니다.

 

우선 속력만큼 이동을 모두 시켜준다면 시간초과가 뜰것 같아서 mod를 사용하였습니다.

상어가 가로로 이동 중이라면 %((M - 1) * 2), 세로로 이동 중이라면 %((N - 1) * 2)만큼만 이동하였습니다.

 

tmp[nx][ny].size가 0이면 상어가 없으므로 상어를 넣어줍니다.

tmp[nx][ny].size가 0이 아니면 이미 다른 상어가 도착한 상태이므로 크기가 큰 상어로 갱신합니다.

 

이 과정을 낚시왕이 맵밖으로 나갈때까지 반복한 후에 크기 합을 출력해줍니다.

 

 

 

 

두 번째 방법입니다.

shark라는 클래스 배열을 이용하여 상어들의 정보를 담아놓습니다. (번호, 좌표(x, y), 속력, 방향, 크기, 죽었는지 여부)

그리고 list배열에는 각 칸에 들어있는 상어의 번호를 저장합니다. (상어가 없으면 0)

 

로직은 첫 번째 방법과 같지만 다른 점은

1번 방법은 N * M을 돌면서 상어가 있는 칸에만 이동을 시키고, 상어의 모든 정보를 이동시켜야하므로 새로운 클래스배열을 선언하였지만

2번 방법은 상어의 수만큼만 반복하면 되고, 인덱스만 이동시키면 되기때문에 새로운 int배열을 선언하였다는 차이입니다.

 

1번 방법
2번 방법
2번 방법에서 mod를 사용하지 않음

시간은 비슷하지만 1번 방법의 메모리가 2번에 비해 엄청 많이 차지하였습니다.

그리고 상어를 움직일 때 mod를 사용하지 않고 돌려보니 시간 차이가 많이 나는것을 알 수 있습니다.

 

 

[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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
 
public class Main {
    static class Pair {
        int speed;
        int d;
        int size;
 
        public Pair(int speed, int d, int size) {
            this.speed = speed;
            this.d = d;
            this.size = size;
        }
    }
 
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static ArrayList<Pair> shark = new ArrayList<>();
    static Pair list[][] = new Pair[101][101];
    static int direct[][] = { { -10 }, { 10 }, { 01 }, { 0-1 } };
    static int N, M, sharkCnt, ans;
 
    static Pair[][] moveShark() {
        Pair tmp[][] = new Pair[101][101];
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) {
                tmp[i][j] = new Pair(000);
            }
        }
 
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) {
                if (list[i][j].size > 0) {
                    int dis = list[i][j].speed;
                    int d = list[i][j].d;
                    int size = list[i][j].size;
 
                    if (d > 1)
                        dis %= ((M - 1* 2);
                    else
                        dis %= ((N - 1* 2);
 
                    int nx = i;
                    int ny = j;
                    for (int k = 0; k < dis; k++) {
                        if (nx == 1 && d == 0)
                            d = 1;
                        else if (nx == N && d == 1)
                            d = 0;
                        else if (ny == 1 && d == 3)
                            d = 2;
                        else if (ny == M && d == 2)
                            d = 3;
 
                        nx += direct[d][0];
                        ny += direct[d][1];
                    }
 
                    if (tmp[nx][ny].size == 0) {
                        tmp[nx][ny].speed = list[i][j].speed;
                        tmp[nx][ny].d = d;
                        tmp[nx][ny].size = size;
                    } else {
                        if (tmp[nx][ny].size < size) {
                            tmp[nx][ny].speed = list[i][j].speed;
                            tmp[nx][ny].d = d;
                            tmp[nx][ny].size = size;
                        }
                    }
                }
            }
        }
 
        return tmp;
    }
 
    static void func() {
        for (int j = 1; j <= M; j++) {
            for (int i = 1; i <= N; i++) {
                if (list[i][j].size > 0) {
                    ans += list[i][j].size;
                    list[i][j].speed = 0;
                    list[i][j].d = 0;
                    list[i][j].size = 0;
                    break;
                }
            }
            if (j == M)
                break;
 
            list = moveShark();
        }
 
        System.out.println(ans);
    }
 
    static void init() {
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++)
                list[i][j] = new Pair(000);
        }
    }
 
    static void input() throws Exception {
        int x, y, s, d, z;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        sharkCnt = Integer.parseInt(st.nextToken());
        init();
        for (int i = 0; i < sharkCnt; i++) {
            st = new StringTokenizer(br.readLine());
            x = Integer.parseInt(st.nextToken());
            y = Integer.parseInt(st.nextToken());
            s = Integer.parseInt(st.nextToken());
            d = Integer.parseInt(st.nextToken());
            z = Integer.parseInt(st.nextToken());
 
            list[x][y].speed = s;
            list[x][y].d = d - 1;
            list[x][y].size = z;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

 

 

[2]

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
 
public class Main {
    static class Pair {
        int idx;
        int x;
        int y;
        int speed;
        int d;
        int size;
        boolean die;
 
        public Pair(int idx, int x, int y, int speed, int d, int size) {
            this.idx = idx;
            this.x = x;
            this.y = y;
            this.speed = speed;
            this.d = d;
            this.size = size;
            this.die = false;
        }
    }
 
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int newlist[][] = new int[101][101];
    static int list[][] = new int[101][101];
    static Pair shark[] = new Pair[10001];
    static int direct[][] = { { -10 }, { 10 }, { 01 }, { 0-1 } };
    static int N, M, sharkCnt, ans;
 
    static void moveShark() {
        for (int i = 1; i <= N; i++)
            Arrays.fill(newlist[i], 0);
 
        for (int i = 1; i <= sharkCnt; i++) {
            int x = shark[i].x;
            int y = shark[i].y;
            int speed = shark[i].speed;
            int d = shark[i].d;
            int size = shark[i].size;
            boolean die = shark[i].die;
 
            if (die)
                continue;
 
            if (d > 1)
                speed %= ((M - 1* 2);
            else
                speed %= ((N - 1* 2);
 
            int nx = x;
            int ny = y;
            for (int k = 0; k < speed; k++) {
                if (nx == 1 && d == 0)
                    d = 1;
                else if (nx == N && d == 1)
                    d = 0;
                else if (ny == 1 && d == 3)
                    d = 2;
                else if (ny == M && d == 2)
                    d = 3;
 
                nx += direct[d][0];
                ny += direct[d][1];
            }
            shark[i].d = d;
 
            if (newlist[nx][ny] == 0) {
                newlist[nx][ny] = i;
                shark[i].x = nx;
                shark[i].y = ny;
            } else {
                int idx = newlist[nx][ny];
                int presize = shark[idx].size;
                if (presize < size) {
                    shark[idx].die = true;
                    newlist[nx][ny] = i;
                    shark[i].x = nx;
                    shark[i].y = ny;
                } else {
                    shark[i].die = true;
                }
            }
        }
    }
 
    static void func() {
        for (int j = 1; j <= M; j++) {
            for (int i = 1; i <= N; i++) {
                if (list[i][j] > 0) {
                    int idx = list[i][j];
                    ans += shark[idx].size;
                    shark[idx].die = true;
                    list[i][j] = 0;
                    break;
                }
            }
            if (j == M)
                break;
 
            moveShark();
            for (int x = 1; x <= N; x++)
                for (int y = 1; y <= M; y++)
                    list[x][y] = newlist[x][y];
        }
 
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        int x, y, s, d, z;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        sharkCnt = Integer.parseInt(st.nextToken());
 
        for (int i = 1; i <= sharkCnt; i++) {
            st = new StringTokenizer(br.readLine());
            x = Integer.parseInt(st.nextToken());
            y = Integer.parseInt(st.nextToken());
            s = Integer.parseInt(st.nextToken());
            d = Integer.parseInt(st.nextToken());
            z = Integer.parseInt(st.nextToken());
 
            shark[i] = new Pair(i, x, y, s, d - 1, z);
            list[x][y] = i;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 1756 피자 굽기  (0) 2024.08.08
boj 3758 KCPC  (0) 2024.06.09
boj 20207 달력  (0) 2021.04.22
boj 17144 미세먼지 안녕!  (0) 2021.04.14
boj 2564 경비원  (0) 2021.04.13

www.acmicpc.net/problem/19236

 

19236번: 청소년 상어

첫째 줄부터 4개의 줄에 각 칸의 들어있는 물고기의 정보가 1번 행부터 순서대로 주어진다. 물고기의 정보는 두 정수 ai, bi로 이루어져 있고, ai는 물고기의 번호, bi는 방향을 의미한다. 방향 bi는

www.acmicpc.net

이 문제는 고려해야할 부분이 많습니다.

 

상어와 물고기는 8방향 이동을 할 수 있습니다.

순서는 (1)상어가 물고기를 먹고 (2)물고기들이 이동합니다.

상어가 처음에는 (0, 0)에 있는 물고기를 먹으며 먹은 물고기의 방향을 갖게되고, 이후에는 주어진 방향으로만 이동합니다.

 

상어는 한 번에 여러 칸을 이동할 수 있고, 물고기가 있는 칸으로만 이동할 수 있습니다.

따라서 이동경로에 있는 물고기 후보 중 하나를 골라 먹습니다.

 

물고기는 맵 밖이나 상어가 있는 칸으로 이동할 수 없으며 이동할 때 번호가 작은 물고기부터 순서대로 이동합니다. (1번 ~ 16번)

(만약, 해당 번호의 물고기가 먹힌상태면 다음 번호가 이동하면 됩니다.)

물고기는 주어진 방향으로만 1칸 이동하며, 그 칸에 물고기가 있으면 서로의 자리를 바꿉니다.

만약 물고기가 이동할 수 없는 경우에는 이동할 수 있을 때까지 방향을 45도 반시계 방향으로 회전한 후 이동합니다.

 

 

이제 제 로직을 설명하겠습니다.

 

저는 입력을 받으면서 (0, 0)에 상어를 미리 놓고, (1)물고기들 이동, (2)상어 이동 순서대로 구현하였습니다.

func함수의 파라미터에 (현재 배열의 상태(arr), 물고기의 상태(f), 상어의 좌표(X, Y), 상어의 방향(D), 현재 먹은 물고기들의 번호합(S))

을 넘겨주는 재귀함수로 구성하였습니다.

 

함수가 돌 때마다 최대 합을 갱신해주었고, 물고기 이동부터 시작합니다.

먹히지 않은 물고기들만 이동하는 방식이며, 물고기가 이동할 수 있을 때까지 방향을 45도씩 반시계방향으로 회전시키며 반복문을 돌렸습니다.

물고기가 이동하고나면 break를 합니다.

 

이제 상어가 이동합니다.

상어는 한 방향으로만 움직일 수 있지만 여러 칸 이동이 가능하므로 맵 밖으로 나갈 때까지 반복문을 돌려줍니다.

물고기가 없는 칸은 갈 수 없으므로 continue를 하였고, 물고기가 있는 칸은 먹은 후의 상태를 다음 재귀로 넘겨주었습니다. (이는 백트래킹으로 구현하였습니다.)

 

상어와 물고기의 모든 이동이 끝나면 계속 갱신해주었던 답을 출력해줍니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static class Pair {
        int x, y, d;
 
        public Pair(int x, int y, int d) {
            this.x = x;
            this.y = y;
            this.d = d;
        }
    }
 
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int direct[][] = { { -10 }, { -1-1 }, { 0-1 }, { 1-1 }, { 10 }, { 11 }, { 01 }, { -11 } };
    static boolean eat[] = new boolean[17];
    static int ans;
 
    static void func(int[][] arr, Pair[] f, int X, int Y, int D, int S) {
        ans = Math.max(ans, S);
        for (int i = 1; i <= 16; i++) {
            if (eat[i])
                continue;
 
            int x = f[i].x;
            int y = f[i].y;
 
            int nx = x;
            int ny = y;
 
            while (true) {
                nx = x + direct[f[i].d][0];
                ny = y + direct[f[i].d][1];
 
                if (nx < 0 || ny < 0 || nx >= 4 || ny >= 4) {
                    f[i].d = (f[i].d + 1) % 8;
                    continue;
                }
                if (arr[nx][ny] == -1) {
                    f[i].d = (f[i].d + 1) % 8;
                    continue;
                }
 
                if (arr[nx][ny] == 0) {
                    f[i].x = nx;
                    f[i].y = ny;
                    arr[nx][ny] = arr[x][y];
                    arr[x][y] = 0;
                } else {
                    int tmp = arr[x][y];
                    f[arr[nx][ny]].x = x;
                    f[arr[nx][ny]].y = y;
                    f[i].x = nx;
                    f[i].y = ny;
                    arr[x][y] = arr[nx][ny];
                    arr[nx][ny] = tmp;
                }
                break;
            }
        }
 
        int nx = X;
        int ny = Y;
        while (true) {
            nx = nx + direct[D][0];
            ny = ny + direct[D][1];
 
            if (nx < 0 || ny < 0 || nx >= 4 || ny >= 4)
                break;
            if (arr[nx][ny] == 0)
                continue;
 
            int tmp = arr[nx][ny];
            arr[nx][ny] = -1;
            arr[X][Y] = 0;
            eat[tmp] = true;
            int arr2[][] = new int[4][4];
            for (int i = 0; i < 4; i++)
                arr2[i] = arr[i].clone();
            Pair f2[] = new Pair[17];
            for (int i = 1; i <= 16; i++)
                f2[i] = new Pair(f[i].x, f[i].y, f[i].d);
            func(arr2, f2, nx, ny, f[tmp].d, S + tmp);
            eat[tmp] = false;
            arr[nx][ny] = tmp;
            arr[X][Y] = -1;
        }
    }
 
    public static void main(String[] args) throws Exception {
        int list[][] = new int[4][4];
        Pair fish[] = new Pair[17];
 
        int nowx = 0, nowy = 0, nowd = 0, sum = 0;
        int x, d;
        for (int i = 0; i < 4; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < 4; j++) {
 
                x = Integer.parseInt(st.nextToken());
                d = Integer.parseInt(st.nextToken()) - 1;
 
                list[i][j] = x;
                fish[x] = new Pair(i, j, d);
                if (i == 0 && j == 0) {
                    list[i][j] = -1;
                    eat[x] = true;
                    nowx = i;
                    nowy = j;
                    nowd = d;
                    sum += x;
                }
            }
        }
        func(list, fish, nowx, nowy, nowd, sum);
        System.out.println(ans);
    }
}
cs

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

boj 30893 트리 게임  (0) 2024.07.19
boj 19542 전단지 돌리기  (0) 2024.06.19
boj 2239 스도쿠  (0) 2021.04.16
boj 2458 키 순서  (0) 2021.04.13
boj 14889 스타트와 링크  (0) 2021.03.17

www.acmicpc.net/problem/17144

 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사

www.acmicpc.net

1초 동안 다음과 같은 일이 일어납니다.

1. 미세먼지가 확산되며 미세먼지가 있는 모든 칸에서 동시에 일어납니다.

 - 인접한 4방향으로 확산됩니다.

 - 인접한 방향이 맵 밖이거나 공기청정기가 있는 곳이라면 확산이 일어나지 않습니다.

 - 확산되는 양은 list[i][j] / 5입니다. (소수점 버림)

 - (i, j)에 남은 미세먼지 양은 list[i][j] - (list[i][j] / 5) * (확산된 방향의 갯수)입니다.

2. 공기청정기가 작동됩니다.

 - 위쪽 공기청정기의 바람은 반시계방향으로 순환, 아래쪽 공기청정기의 바람은 시계방향으로 순환합니다.

 - 미세먼지가 바람의 방향대로 한 칸씩 이동합니다.

 - 공기청정기로 들어가는 미세먼지는 정화됩니다.

 

위의 모든것을 직접 구현해야합니다.

 

우선 2중for문을 돌면서 미세먼지를 확산시킵니다. 이 때 확산이 동시에 일어나야하므로 nextlist라는 변수를 사용하였습니다.

그 다음 공기청정기를 작동시켜 위쪽에는 반시계방향으로, 아래쪽에는 시계방향으로 값을 회전시켜줍니다.

이 과정을 T번 반복하여 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
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
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 int list[][] = new int[51][51];
    static int nextlist[][] = new int[51][51];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int cleaner[][] = new int[2][2];
    static int N, M, T;
 
    static void clear() {
        int x = cleaner[0][0];
        int y = cleaner[0][1];
 
        x--;
        int d = 3;
        while (true) {
            int nx = x + direct[d][0];
            int ny = y + direct[d][1];
 
            if (nx <= 0 || ny <= 0 || nx > cleaner[0][0|| ny > M) {
                d = (d + 1) % 4;
                continue;
            }
            list[x][y] = 0;
            if (list[nx][ny] == -1)
                break;
 
            list[x][y] = list[nx][ny];
            x = nx;
            y = ny;
        }
 
        x = cleaner[1][0];
        y = cleaner[1][1];
 
        x++;
        d = 1;
        while (true) {
            int nx = x + direct[d][0];
            int ny = y + direct[d][1];
 
            if (nx < cleaner[1][0|| ny <= 0 || nx > N || ny > M) {
                d = (d + 3) % 4;
                continue;
            }
            list[x][y] = 0;
            if (list[nx][ny] == -1)
                break;
 
            list[x][y] = list[nx][ny];
            x = nx;
            y = ny;
        }
    }
    
    static void spread() {
        for (int i = 1; i <= N; i++)
            Arrays.fill(nextlist[i], 0);
 
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) {
                if (list[i][j] > 0) {
                    int diff = list[i][j] / 5;
                    int cnt = 0;
                    for (int d = 0; d < 4; d++) {
                        int nx = i + direct[d][0];
                        int ny = j + direct[d][1];
 
                        if (nx <= 0 || ny <= 0 || nx > N || ny > M)
                            continue;
                        if (list[nx][ny] == -1)
                            continue;
 
                        nextlist[nx][ny] += diff;
                        cnt++;
                    }
 
                    nextlist[i][j] += (list[i][j] - diff * cnt);
                }
            }
        }
        
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) {
                if (list[i][j] == -1)
                    continue;
                list[i][j] = nextlist[i][j];
            }
        }
    }
 
    static void func() {
        for (int t = 1; t <= T; t++) {
            spread();
            clear();
        }
    }
 
    static void print() {
        int ans = 0;
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) {
                if (list[i][j] > 0)
                    ans += list[i][j];
            }
        }
 
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        int t = 0;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        T = Integer.parseInt(st.nextToken());
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= M; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
                if (list[i][j] == -1) {
                    cleaner[t][0= i;
                    cleaner[t++][1= j;
                }
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

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

boj 17143 낚시왕  (0) 2021.04.23
boj 20207 달력  (0) 2021.04.22
boj 2564 경비원  (0) 2021.04.13
boj 16719 ZOAC  (0) 2021.03.15
boj 3085 사탕 게임  (0) 2021.02.26

www.acmicpc.net/problem/11559

 

11559번: Puyo Puyo

총 12개의 줄에 필드의 정보가 주어지며, 각 줄에는 6개의 문자가 있다. 이때 .은 빈공간이고 .이 아닌것은 각각의 색깔의 뿌요를 나타낸다. R은 빨강, G는 초록, B는 파랑, P는 보라, Y는 노랑이다.

www.acmicpc.net

같은 색 뿌요가 4개이상 상하좌우 4방향으로 연결되어있으면 터집니다.

뿌요들이 없어지고나서 남은 뿌요들은 아래로 모두 이동시켜줍니다.

그렇게 모인 뿌요들 중 같은 색 뿌요가 4개이상 모이게 되면 다시 터집니다. => 연쇄가 추가됩니다.

이 과정을 뿌요가 터지지 않을때까지 반복하여 몇 연쇄가 일어나는지 출력하는 문제입니다.

 

저의 로직은 다음과 같습니다.

1. 12 * 6 배열을 돌면서 뿌요가 있는 칸이면 bfs로 몇개가 모여있는지 확인

2. 4개이상 모여있으면 모여있는 뿌요들 제거 => 이 때 제거할 뿌요는 ArrayList에 넣었습니다.

3. 제거된 뿌요가 없으면 t - 1를 출력 후 리턴하고 아니면 다음으로 넘어갑니다.

4. 제거된 뿌요로 인해 빈칸을 위의 뿌요들로 채워줍니다. (뿌요들을 아래로 내려줍니다.)

 

3번에서 t - 1을 출력하는 이유는 몇 번 연쇄인지 출력하는 문제인데 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
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.ArrayList;
import java.util.Arrays;
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 list[][] = new char[12][6];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static ArrayList<int[]> erasepoint = new ArrayList<>();
    static boolean visit[][] = new boolean[12][6];
    static int cnt;
 
    static void bfs(int sx, int sy) {
        Deque<int[]> dq = new ArrayDeque<>();
        dq.add(new int[] { sx, sy });
        visit[sx][sy] = true;
        cnt = 0;
        while (!dq.isEmpty()) {
            int x = dq.peek()[0];
            int y = dq.poll()[1];
            erasepoint.add(new int[] { x, y });
            cnt++;
 
            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 >= 12 || ny >= 6)
                    continue;
                if (visit[nx][ny] || list[nx][ny] != list[x][y])
                    continue;
 
                dq.add(new int[] { nx, ny });
                visit[nx][ny] = true;
            }
        }
    }
 
    static void func() {
        for (int t = 1;; t++) {
            boolean chk = false;
            for (int i = 0; i < 12; i++)
                Arrays.fill(visit[i], false);
 
            for (int i = 0; i < 12; i++) {
                for (int j = 0; j < 6; j++) {
                    if (list[i][j] == '.')
                        continue;
                    bfs(i, j);
                    if (cnt >= 4) {
                        chk = true;
                        for (int xy[] : erasepoint) {
                            list[xy[0]][xy[1]] = '.';
                        }
                    }
                    erasepoint.clear();
                }
            }
 
            if (!chk) {
                System.out.println(t - 1);
                return;
            }
 
            for (int i = 10; i >= 0; i--) {
                for (int j = 0; j < 6; j++) {
                    if (list[i][j] == '.')
                        continue;
 
                    for (int k = i + 1; k < 12; k++) {
                        if (list[k][j] != '.') {
                            char tmp = list[i][j];
                            list[i][j] = list[k - 1][j];
                            list[k - 1][j] = tmp;
                            break;
                        } else {
                            if (k == 11) {
                                char tmp = list[i][j];
                                list[i][j] = list[k][j];
                                list[k][j] = tmp;
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
 
    static void input() throws Exception {
        for (int i = 0; i < 12; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = st.nextToken().toCharArray();
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 1600 말이 되고픈 원숭이  (0) 2021.03.24
boj 2589 보물섬  (0) 2021.03.16
boj 15653 구슬 탈출 4  (0) 2021.02.22
boj 1525 퍼즐  (0) 2021.02.19
boj 7576 토마토  (0) 2021.02.19

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

 

17135번: 캐슬 디펜스

첫째 줄에 격자판 행의 수 N, 열의 수 M, 궁수의 공격 거리 제한 D가 주어진다. 둘째 줄부터 N개의 줄에는 격자판의 상태가 주어진다. 0은 빈 칸, 1은 적이 있는 칸이다.

www.acmicpc.net

알고리즘 분류는 bfs지만 조합 + 정렬 + 시뮬레이션 + 구현 등 사용해야할 기법이 많았습니다.

 

제가 처음 접근한 방법은

우선 조합으로 궁수가 있을 자리를 모두 구해준 다음

bfs로 4방향 탐색하여 공격가능한 적을 모두 담아놓고 정렬하여 맨 첫번째에 있는 적만 제거하였고

그 다음 적들을 모두 아래로 내려 다음 bfs탐색을 하는 방식이었습니다.

 

위의 방법으로 AC를 받았지만 시간적인 손해가 많다는 생각이 들었고, 시간을 줄이기위해 다른 방법을 생각하였습니다.

 

궁수는 항상 N + 1번째 행에 있기때문에 밑을 볼 필요가 없습니다. 그래서 왼쪽, 위, 오른쪽만 탐색하면 됩니다.

여기서 문제 조건을 보시면 가장 가까운 적이 여러명이면 가장 왼쪽에 있는 적을 공격한다고 나와있습니다.

위의 조건에서 왼쪽 -> 위 -> 오른쪽 방향 순서로 탐색하면 무조건 공격해야할 대상을 먼저 찾는다는 결론이 나왔습니다. 이제 정렬은 사용하지 않아도됩니다.

 

그 다음 여러명의 궁수가 한명의 적을 공격할 수 있기때문에 궁수가 공격할 대상을 찾으면

boolean배열을 사용하여 true로 바꿔주었고, 이중 for문으로 true인 좌표의 list를 0으로 바꿔주었지만

int배열을 사용하여 모든 좌표를 다 넣어주었고, 하나의 for문으로 해결할 수 있었습니다.

 

마지막으로 적을 제거하고 난 후에 이중 for문을 돌려서 적이 모두 제거되었는지 확인하였습니다.

제거되었으면 break를 해주고, 아니면 적들을 아래로 내려야합니다.

하지만 저는 적들을 아래로 내리는것보다 궁수를 위로 올리는 것이 시간상 효율적이라는 것을 깨닫고 궁수를 위로 올리기 위해 n--를 하였습니다.

 

최종적으로 저의 로직은 이렇습니다.

1. 조합으로 궁수를 배치

2. bfs로 3방향 탐색하여 공격할 수 있는 적을 탐색 (적을 찾거나 D보다 거리가 커지면 break)

3. 2번에서 찾은 적 제거

4. 적이 모두 제거되었는지 확인

5. 적이 모두 제거되었으면 break, 아니면 궁수 한 칸 위로 이동(n--)

 

자바에서 Collection사용이 많아지면 시간적으로 비효율적이라고 생각해서 배열을 최대한 사용하였습니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
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[][] = { { 0-1 }, { -10 }, { 01 } };
    static int list[][], copylist[][], attacker[], rkill[][];
    static int N, M, D, ans, kidx;
 
    static void bfs() {
        int n = N;
        int sum = 0;
        Deque<int[]> dq = new ArrayDeque<int[]>();
        ArrayList<int[]> kill = new ArrayList<>();
        while (true) {
            for (int k = 0; k < 3; k++) {
                dq.addLast(new int[] { n, attacker[k], 0 });
                for (int i = 0; i < n; i++)
                    Arrays.fill(visit[i], false);
 
                while (!dq.isEmpty()) {
                    int x = dq.peekFirst()[0];
                    int y = dq.peekFirst()[1];
                    int cnt = dq.pollFirst()[2];
 
                    if (cnt == D) {
                        dq.clear();
                        break;
                    }
                    boolean chk = false;
                    for (int i = 0; i < 3; 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])
                            continue;
                        if (copylist[nx][ny] == 1) {
                            chk = true;
                            kill.add(new int[] { nx, ny, cnt + 1 });
                            break;
                        } else {
                            dq.addLast(new int[] { nx, ny, cnt + 1 });
                            visit[nx][ny] = true;
                        }
                    }
                    if (chk)
                        break;
                }
                dq.clear();
 
                if (kill.isEmpty())
                    continue;
 
                rkill[kidx][0= kill.get(0)[0];
                rkill[kidx++][1= kill.get(0)[1];
                kill.clear();
            }
 
            for (int i = 0; i < kidx; i++) {
                if (copylist[rkill[i][0]][rkill[i][1]] == 1) {
                    copylist[rkill[i][0]][rkill[i][1]] = 0;
                    sum++;
                }
            }
            kidx = 0;
 
            boolean allkill = false;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < M; j++) {
                    if (copylist[i][j] == 1) {
                        allkill = true;
                        break;
                    }
                }
                if (allkill)
                    break;
            }
            if (!allkill)
                break;
            n--;
        }
 
        ans = Math.max(ans, sum);
    }
 
    static void func(int idx, int cnt) {
        if (cnt == 3) {
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < M; j++)
                    copylist[i][j] = list[i][j];
            }
            bfs();
            return;
        }
 
        for (int i = idx; i < M; i++) {
            attacker[cnt] = i;
            func(i + 1, cnt + 1);
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        D = Integer.parseInt(st.nextToken());
        list = new int[N][M];
        copylist = new int[N][M];
        attacker = new int[3];
        visit = new boolean[N][M];
        rkill = new int[226][2];
 
        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());
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(00);
        System.out.println(ans);
    }
}
cs

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

boj 1525 퍼즐  (0) 2021.02.19
boj 7576 토마토  (0) 2021.02.19
boj 16236 아기 상어  (0) 2021.02.14
boj 10026 적록색약  (0) 2021.02.13
boj 2206 벽 부수고 이동하기  (0) 2021.02.13

www.acmicpc.net/problem/17406

 

17406번: 배열 돌리기 4

크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의

www.acmicpc.net

앞의 배열 돌리기1, 2와 같이 배열이 주어지고 이 문제는 회전시킬 구간이 추가로 주어집니다.

구간은 r c s 이렇게 들어오는데 구간 (r - s, c - s) ~ (r + s, c + s)를 1번 회전시켜라는 뜻입니다.

하지만 이 연산 순서를 임의로 정해서 배열 A의 값을 최소로 해야하는 문제입니다.

즉, 구간정보를 브루트포스방식을 사용하여 모든 순서로 연산을 다 해봐야합니다.

 

연산 순서는 ArrayList를 활용하여 구간을 넣었다 뺐다 하는 방식으로 정하였고, 순서를 모두 정하면 list의 값을 복사한 다른 배열을 선언하여 모든 회전을 수행한 후에 A의 최솟값을 구하였습니다.

 

회전 로직은 1번, 2번과 같지만 구간에 해당하는 숫자가 1개인 경우 next로 자신으로 설정하는 예외처리를 해주었습니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int direct[][] = { { 10 }, { 01 }, { -10 }, { 0-1 } };
    static ArrayList<int[]> rotate = new ArrayList<>();
    static ArrayList<int[]> rotatesolve = new ArrayList<>();
    static boolean visit[][], chk[];
    static int list[][], clist[][];
    static int N, M, K, r, c, s;
    static int sx, sy, ex, ey, ans = Integer.MAX_VALUE;
 
    static void print() {
        System.out.println(ans);
    }
 
    static int dfs(int x, int y, int idx) {
        visit[x][y] = true;
 
        int nx = x + direct[idx][0];
        int ny = y + direct[idx][1];
 
        if (nx < sx || ny < sy || nx > ex || ny > ey) {
            idx++;
            nx = x + direct[idx][0];
            ny = y + direct[idx][1];
            if (nx < sx || ny < sy || nx > ex || ny > ey) {
                nx = x;
                ny = y;
            }
        }
 
        if (visit[nx][ny]) {
            int tmp = clist[x][y];
            clist[x][y] = clist[nx][ny];
            return tmp;
        }
 
        int tmp = clist[x][y];
        clist[x][y] = dfs(nx, ny, idx);
        return tmp;
    }
 
    static void solve(int rr, int cc, int ss) {
        sx = rr - ss;
        sy = cc - ss;
        ex = rr + ss;
        ey = cc + ss;
 
        for (int i = 0;; i++) {
            dfs(sx, sy, 0);
            sx++;
            sy++;
            ex--;
            ey--;
            if (sx > ex || sy > ey)
                break;
        }
 
        for (int i = rr - ss; i <= rr + ss; i++) {
            Arrays.fill(visit[i], false);
        }
    }
 
    static void func(int cnt) {
        if (cnt == K) {
            for (int i = 1; i <= N; i++) {
                for (int j = 1; j <= M; j++)
                    clist[i][j] = list[i][j];
            }
            for (int i = 0; i < K; i++) {
                solve(rotatesolve.get(i)[0], rotatesolve.get(i)[1], rotatesolve.get(i)[2]);
            }
 
            for (int i = 1; i <= N; i++) {
                int sum = 0;
                for (int j = 1; j <= M; j++) {
                    sum += clist[i][j];
                }
                ans = Math.min(ans, sum);
            }
 
            return;
        }
 
        for (int i = 0; i < K; i++) {
            if (chk[i])
                continue;
 
            rotatesolve.add(rotate.get(i));
            chk[i] = true;
            func(cnt + 1);
            chk[i] = false;
            rotatesolve.remove(cnt);
        }
    }
 
    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());
        list = new int[N + 1][M + 1];
        clist = new int[N + 1][M + 1];
        visit = new boolean[N + 1][M + 1];
 
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= M; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
            }
        }
 
        for (int i = 0; i < K; i++) {
            st = new StringTokenizer(br.readLine());
            r = Integer.parseInt(st.nextToken());
            c = Integer.parseInt(st.nextToken());
            s = Integer.parseInt(st.nextToken());
            rotate.add(new int[] { r, c, s });
        }
 
        chk = new boolean[K];
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(0);
        print();
    }
}
cs

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

boj 1987 알파벳  (0) 2021.02.18
boj 3109 빵집  (0) 2021.02.18
boj 16927 배열 돌리기 2  (0) 2021.02.10
boj 16926 배열 돌리기 1  (0) 2021.02.10
boj 1068 트리  (0) 2021.02.09

www.acmicpc.net/problem/16927

 

16927번: 배열 돌리기 2

크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2][1] A[2][2] ← A[2][3] ← A[2][4] A[2][5]

www.acmicpc.net

 

emoney96.tistory.com/110

 

boj 16926 배열 돌리기 1

www.acmicpc.net/problem/16926 16926번: 배열 돌리기 1 크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ←..

emoney96.tistory.com

위의 문제풀이와 동일합니다.

 

이 문제는 많은 회전으로 인한 TLE가 발생할 수 있는 문제였지만 저는 이전문제에서 이미 해줬던 부분이라 바로 AC를 받았습니다.

 

 

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
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 int visit[][];
    static int list[][];
    static int N, M, R;
    static int sx, sy, ex, ey;
 
    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 int dfs(int x, int y, int idx) {
        visit[x][y]++;
 
        int nx = x + direct[idx][0];
        int ny = y + direct[idx][1];
 
        if (nx < sx || ny < sy || nx > ex || ny > ey) {
            idx++;
            nx = x + direct[idx][0];
            ny = y + direct[idx][1];
        }
 
        if (visit[nx][ny] == visit[x][y]) {
            int tmp = list[x][y];
            list[x][y] = list[nx][ny];
            return tmp;
        }
 
        int tmp = list[x][y];
        list[x][y] = dfs(nx, ny, idx);
        return tmp;
    }
 
    static void solve() {
        sx = 0;
        sy = 0;
        ex = N - 1;
        ey = M - 1;
        int n = N;
        int m = M;
        for (int i = 0;; i++) {
            for (int j = 0; j < R % ((n - 1* 2 + (m - 1* 2); j++) {
                dfs(i, i, 0);
            }
            sx++;
            sy++;
            ex--;
            ey--;
            n -= 2;
            m -= 2;
            if (sx > ex || sy > ey)
                break;
        }
    }
 
    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];
        visit = new int[N][M];
 
        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());
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        solve();
        print();
    }
}
cs

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

boj 3109 빵집  (0) 2021.02.18
boj 17406 배열 돌리기 4  (0) 2021.02.10
boj 16926 배열 돌리기 1  (0) 2021.02.10
boj 1068 트리  (0) 2021.02.09
boj 9202 Boggle  (0) 2021.02.02

www.acmicpc.net/problem/16926

 

16926번: 배열 돌리기 1

크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2][1] A[2][2] ← A[2][3] ← A[2][4] A[2][5]

www.acmicpc.net

입력으로 들어오는 배열을 이런식으로 회전시킨 결과를 출력하는 문제입니다..

무작정 짜보려고 했다가 소스만 두번정도 갈아엎고 찾은 솔루션이 dfs 방법입니다.

 

바깥쪽 그룹부터 안쪽 그룹 순서대로 회전하기때문에 시작지점은 항상 (i, i)입니다.

우선 가장 바깥쪽 그룹부터 구간을 (0, 0) ~ (N - 1, M - 1)으로 잡고 R번 회전 시킨 후에

구간을 (+1, +1), ~ (-1, -1)씩 하고 다음 그룹도 똑같이 회전시켜줍니다. (구간 범위가 벗어나면 break)

 

dfs에서는 방문처리를 count식으로 방문 횟수를 갱신하였습니다.

next가 범위를 벗어나면 방향을 바꾸고 next를 다시 구해줍니다.

만약 next의 방문횟수와 자신의 방문횟수가 같으면 한바퀴를 돌았다는 뜻이 됩니다.

=> list[x][y]에 list[nx][ny]를 넣고 원래 자신의 값을 리턴합니다.

그러면 이제 리턴되는 값들을 모두 받게되면 회전 1번을 하게 된것입니다.

 

그리고 회전시킬 때 회전시키는 배열의 크기 (n - 1) * 2 + (m - 1) * 2번이 한바퀴이므로 mod 연산을 통해 R을 낮춰준 후에 회전시켜줍니다. 다음 구간으로 넘어가면 크기를 2만큼 줄여줘야합니다.

 

 

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
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 int visit[][];
    static int list[][];
    static int N, M, R;
    static int sx, sy, ex, ey;
 
    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 int dfs(int x, int y, int idx) {
        visit[x][y]++;
 
        int nx = x + direct[idx][0];
        int ny = y + direct[idx][1];
 
        if (nx < sx || ny < sy || nx > ex || ny > ey) {
            idx++;
            nx = x + direct[idx][0];
            ny = y + direct[idx][1];
        }
 
        if (visit[nx][ny] == visit[x][y]) {
            int tmp = list[x][y];
            list[x][y] = list[nx][ny];
            return tmp;
        }
 
        int tmp = list[x][y];
        list[x][y] = dfs(nx, ny, idx);
        return tmp;
    }
 
    static void solve() {
        sx = 0;
        sy = 0;
        ex = N - 1;
        ey = M - 1;
        int n = N;
        int m = M;
        for (int i = 0;; i++) {
            for (int j = 0; j < R % ((n - 1* 2 + (m - 1* 2); j++) {
                dfs(i, i, 0);
            }
            sx++;
            sy++;
            ex--;
            ey--;
            n -= 2;
            m -= 2;
            if (sx > ex || sy > ey)
                break;
        }
    }
 
    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];
        visit = new int[N][M];
 
        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());
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        solve();
        print();
    }
}
cs

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

boj 17406 배열 돌리기 4  (0) 2021.02.10
boj 16927 배열 돌리기 2  (0) 2021.02.10
boj 1068 트리  (0) 2021.02.09
boj 9202 Boggle  (0) 2021.02.02
boj 15666 N과 M (12)  (0) 2021.01.31

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

+ Recent posts