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 2239 스도쿠  (0) 2021.04.16
boj 2458 키 순서  (0) 2021.04.13
boj 14889 스타트와 링크  (0) 2021.03.17
boj 2023 신기한 소수  (0) 2021.03.16
boj 14500 테트로미노  (0) 2021.03.15

www.acmicpc.net/problem/2239

 

2239번: 스도쿠

스도쿠는 매우 간단한 숫자 퍼즐이다. 9×9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3×3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다

www.acmicpc.net

백트래킹 기본문제 중 하나입니다.

우선 스도쿠는 9 * 9 배열이 있을 때 각 행, 열, 3 * 3구간에서 1 ~ 9가 한 번씩만 나오게 하는 문제입니다.

 

그럼 각 행, 열, 구간을 중복체크하는 배열을 세개 사용합니다.

(0, 0)부터 (8, 8)까지 한 칸씩 확인하며, list[x][y] != 0이면 수를 넣을 필요가 없으므로 바로 다음좌표를 탐색합니다.

list[x][y] == 0이면 1 ~ 9까지 넣을 수 있는지 확인합니다.

(x, y)에서 숫자 i가 x행에서 사용되었는지, y열에서 사용되었는지, 같은 구간에서 사용되었는지 각각 확인해줍니다.

세 구간 모두 사용되지 않은 숫자만 list[x][y]에 넣어주고 다음좌표로 넘겨줍니다.

모든 좌표를 탐색하였으면 답을 출력하고 리턴합니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static char div[][] = { { 'a''a''a''b''b''b''c''c''c' },
            { 'a''a''a''b''b''b''c''c''c' }, { 'a''a''a''b''b''b''c''c''c' },
            { 'd''d''d''e''e''e''f''f''f' }, { 'd''d''d''e''e''e''f''f''f' },
            { 'd''d''d''e''e''e''f''f''f' }, { 'g''g''g''h''h''h''i''i''i' },
            { 'g''g''g''h''h''h''i''i''i' }, { 'g''g''g''h''h''h''i''i''i' }, };
    static boolean rowsChk[][] = new boolean[10][10];
    static boolean colsChk[][] = new boolean[10][10];
    static boolean divChk[][] = new boolean[10][10];
    static int list[][] = new int[10][10];
 
    static boolean func(int x, int y) {
        if (x == 9) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < 9; i++) {
                for (int j = 0; j < 9; j++) {
                    sb.append(list[i][j]);
                }
                sb.append("\n");
            }
            System.out.println(sb.toString());
            return true;
        }
 
        int nx = x;
        int ny = y + 1;
        if (ny == 9) {
            nx++;
            ny = 0;
        }
 
        if (list[x][y] != 0)
            return func(nx, ny);
        else {
            for (int i = 1; i <= 9; i++) {
                if (rowsChk[x][i] || colsChk[y][i] || divChk[div[x][y] - 'a'][i])
                    continue;
 
                rowsChk[x][i] = true;
                colsChk[y][i] = true;
                divChk[div[x][y] - 'a'][i] = true;
                list[x][y] = i;
                boolean chk = func(nx, ny);
                if (chk)
                    return true;
                list[x][y] = 0;
                divChk[div[x][y] - 'a'][i] = false;
                colsChk[y][i] = false;
                rowsChk[x][i] = false;
            }
        }
 
        return false;
    }
 
    static void input() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        char ch[];
        for (int i = 0; i < 9; i++) {
            st = new StringTokenizer(br.readLine());
            ch = st.nextToken().toCharArray();
            for (int j = 0; j < 9; j++) {
                list[i][j] = ch[j] - '0';
                if (list[i][j] != 0) {
                    rowsChk[i][list[i][j]] = true;
                    colsChk[j][list[i][j]] = true;
                    divChk[div[i][j] - 'a'][list[i][j]] = true;
                }
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(00);
    }
}
cs

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

boj 19236 청소년 상어  (0) 2021.04.22
boj 2458 키 순서  (0) 2021.04.13
boj 14889 스타트와 링크  (0) 2021.03.17
boj 2023 신기한 소수  (0) 2021.03.16
boj 14500 테트로미노  (0) 2021.03.15

www.acmicpc.net/problem/14889

 

14889번: 스타트와 링크

예제 2의 경우에 (1, 3, 6), (2, 4, 5)로 팀을 나누면 되고, 예제 3의 경우에는 (1, 2, 4, 5), (3, 6, 7, 8)로 팀을 나누면 된다.

www.acmicpc.net

조합으로 N/2개를 뽑은 후에 뽑은 것들의 조합의 능력치를 N^2으로 각각 계산해줍니다.

그 다음 abs(a-b)의 차이의 최소를 구해 출력해주시면 됩니다.

 

 

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 pick[] = new boolean[21];
    static int list[][] = new int[21][21];
    static int N, ans = Integer.MAX_VALUE;
 
    static void func(int idx, int cnt) {
        if (cnt == N / 2) {
            int a = 0;
            int b = 0;
            for (int i = 0; i < N; i++) {
                for (int j = i + 1; j < N; j++) {
                    if (pick[i] == pick[j]) {
                        if (pick[i])
                            a += (list[i][j] + list[j][i]);
                        else
                            b += (list[i][j] + list[j][i]);
                    }
                }
            }
 
            ans = Math.min(ans, Math.abs(a - b));
            return;
        }
 
        for (int i = idx; i < N; i++) {
            pick[i] = true;
            func(i + 1, cnt + 1);
            pick[i] = false;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; 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 > dfs' 카테고리의 다른 글

boj 2239 스도쿠  (0) 2021.04.16
boj 2458 키 순서  (0) 2021.04.13
boj 2023 신기한 소수  (0) 2021.03.16
boj 14500 테트로미노  (0) 2021.03.15
boj 16922 로마 숫자 만들기  (0) 2021.02.24

www.acmicpc.net/problem/2023

 

2023번: 신기한 소수

수빈이가 세상에서 가장 좋아하는 것은 소수이고, 취미는 소수를 가지고 노는 것이다. 요즘 수빈이가 가장 관심있어 하는 소수는 7331이다. 7331은 소수인데, 신기하게도 733도 소수이고, 73도 소수

www.acmicpc.net

메모리 제한이 4MB이라서 에라토스테네스의 체를 사용할 수 없습니다.

그래서 소수인지 판별하는 부분을 2부터 반복문을 돌리는 방법을 선택해서 시간초과가 뜰것 같았지만 다행히도 AC를 받았습니다.

 

우선 문제의 7331을 보면 7331도 소수, 733도 소수, 73도 소수, 7도 소수입니다.

즉 일의자리부터 숫자 하나씩 뺀 부분 숫자도 소수여야합니다.

 

저는 백트래킹으로 맨 앞의 자리부터 구하였습니다.

우선 맨 앞의 자리에 올 수 있는 숫자는 2, 3, 5, 7입니다. (일의자리 소수)

각 숫자가 맨 앞의 올 경우를 구하기 위해 4번의 dfs를 돌립니다.

 

dfs에서는 일의자리로 올 숫자를 구하는것이기 때문에 짝수가 올 수 없으므로 홀수만 돌려줍니다.

next가 소수이면 재귀를 돌려주었고, 뽑은 숫자가 N개가 되면 지금까지 뽑은 숫자를 출력합니다.

 

 

[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
#include <iostream>
using namespace std;
 
int N;
 
bool prime(int x) {
    for (int i = 2; i*<= x; i++) {
        if (!(x % i)) return false;
    }
 
    return true;
}
 
void dfs(int cnt, int x) {
    if (cnt == N) {
        cout << x << '\n';
        return;
    }
 
    for (int i = 1; i <= 9; i += 2) {
        int next = x * 10 + i;
        if (!prime(next)) continue;
        dfs(cnt + 1, next);
    }
}
 
void func() {
    dfs(12);
    dfs(13);
    dfs(15);
    dfs(17);
}
 
void input() {
    cin >> N;
}
 
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
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 boolean primeCheck(int x) {
        for (int i = 2; i * i <= x; i++) {
            if (x % i == 0)
                return false;
        }
 
        return true;
    }
 
    static void dfs(int cnt, int x) {
        if (cnt == N) {
            sb.append(x).append("\n");
            return;
        }
 
        for (int i = 1; i <= 9; i += 2) {
            int next = x * 10 + i;
            if (!primeCheck(next))
                continue;
 
            dfs(cnt + 1, next);
        }
    }
 
    static void func() {
        dfs(12);
        dfs(13);
        dfs(15);
        dfs(17);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        System.out.print(sb.toString());
    }
}
cs

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

boj 2458 키 순서  (0) 2021.04.13
boj 14889 스타트와 링크  (0) 2021.03.17
boj 14500 테트로미노  (0) 2021.03.15
boj 16922 로마 숫자 만들기  (0) 2021.02.24
boj 1987 알파벳  (0) 2021.02.18

www.acmicpc.net/problem/16922

 

16922번: 로마 숫자 만들기

2, 6, 10, 11, 15, 20, 51, 55, 60, 100을 만들 수 있다.

www.acmicpc.net

1, 5, 10, 50을 배열에 넣어놓고 조합으로 해결하였습니다.

인덱스와 갯수와 합을 유지시키면서 재귀를 돌려줍니다.

N개를 뽑으면 숫자를 저장하였는데 이 때 중복된 값을 넣으면 안되므로 set에 넣어줍니다.

함수가 끝나고 최종 set의 크기를 출력하시면 됩니다.

 

 

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
#include <iostream>
#include <set>
using namespace std;
 
set<int> s;
int list[4];
int N;
 
void init() {
    list[0= 1;
    list[1= 5;
    list[2= 10;
    list[3= 50;
}
 
void func(int idx, int cnt, int sum) {
    if (cnt == N) {
        if (sum > 0) s.insert(sum);
        return;
    }
 
    for (int i = idx; i < 4; i++) {
        func(i, cnt + 1, sum + list[i]);
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    cin >> N;
    init();
    func(000);
    cout << s.size() << '\n';
 
    return 0;
}
cs

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

boj 2023 신기한 소수  (0) 2021.03.16
boj 14500 테트로미노  (0) 2021.03.15
boj 1987 알파벳  (0) 2021.02.18
boj 3109 빵집  (0) 2021.02.18
boj 17406 배열 돌리기 4  (0) 2021.02.10

www.acmicpc.net/problem/1987

 

1987번: 알파벳

세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다. 말은 상하좌우로 인접한 네 칸 중의 한 칸으

www.acmicpc.net

 

문제에서 요구하는 조건은

1. 말은 (0, 0)에서 출발합니다.

2. 말은 상하좌우 방향으로 움직일 수 있습니다.

3. 말이 지나가는 동안 밟은 칸의 알파벳은 모두 달라야합니다.

 

말이 (0, 0)에서 출발하여 지나갈 수 있는 최대의 칸 수를 출력해야합니다.

저는 백트래킹으로 해결하였고 해당 칸을 방문체크하는 visit배열과 칸에 있는 알파벳 중복체크를 위한 alphachk 배열을 사용하였습니다.

 

재귀를 돌릴때마다 답을 갱신해주고, 해당 칸과 알파벳에 방문처리합니다.

그 다음 4방향 탐색하여 맵 밖으로 나갔는지, 이미 방문하였거나 밟은 적이 있는 알파벳인지 체크를 해줍니다.

모두 통과하면 nx, ny, cnt+1를 재귀로 넘겨주고, 빠져나오면 true했던 boolean배열을 모두 false로 바꿔줍니다.

마지막으로 정답을 출력합니다.

 

 

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
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 boolean visit[][], alphachk[];
    static char list[][];
    static int N, M, ans;
 
    static void dfs(int x, int y, int cnt) {
        ans = Math.max(ans, cnt);
        visit[x][y] = true;
        alphachk[list[x][y] - 'A'= true;
 
        for (int i = 0; i < 4; i++) {
            int nx = x + direct[i][0];
            int ny = y + direct[i][1];
 
            if (nx < 0 || ny < 0 || nx >= N || ny >= M)
                continue;
            if (visit[nx][ny] || alphachk[list[nx][ny] - 'A'])
                continue;
 
            dfs(nx, ny, cnt + 1);
            alphachk[list[nx][ny] - 'A'= false;
            visit[nx][ny] = false;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new char[N][];
        visit = new boolean[N][M];
        alphachk = new boolean[26];
 
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = st.nextToken().toCharArray();
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        dfs(001);
        System.out.println(ans);
    }
}
cs

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

boj 14500 테트로미노  (0) 2021.03.15
boj 16922 로마 숫자 만들기  (0) 2021.02.24
boj 3109 빵집  (0) 2021.02.18
boj 17406 배열 돌리기 4  (0) 2021.02.10
boj 16927 배열 돌리기 2  (0) 2021.02.10

www.acmicpc.net/problem/15666

 

15666번: N과 M (12)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

N과M 마지막 문제입니다.

 

11번과 다른점은 수열을 비내림차순으로 골라야한다는 점입니다.

그래서 재귀함수를 돌릴 때 이전에 고른 인덱스 관리를 해주어야 합니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
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 StringBuffer sb = new StringBuffer();
    static ArrayList<Integer> list, ans;
    static Set<ArrayList<Integer>> s = new HashSet<>();
    static int N, M;
 
    static void dfs(int idx, int cnt) {
        if (cnt == M) {
            if (s.contains(ans))
                return;
 
            s.add(ans);
            for (int i = 0; i < ans.size(); i++) {
                sb.append(ans.get(i) + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = idx; i < N; i++) {
            int x = list.get(i);
 
            ans.add(x);
            dfs(i, cnt + 1);
            ans.remove(cnt);
        }
    }
 
    static void input() throws Exception {
        list = new ArrayList<>();
        ans = new ArrayList<>();
 
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            int x = Integer.parseInt(st.nextToken());
            list.add(x);
        }
 
        Collections.sort(list);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        dfs(00);
        System.out.println(sb.toString());
    }
}
cs

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

boj 1068 트리  (0) 2021.02.09
boj 9202 Boggle  (0) 2021.02.02
boj 15665 N과 M (11)  (0) 2021.01.30
boj 15664 N과 M (10)  (0) 2021.01.30
boj 15663 N과 M (9)  (0) 2021.01.28

www.acmicpc.net/problem/15665

 

15665번: N과 M (11)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

N과M 11번째 문제입니다.

 

10번과 다른점은 같은수를 골라도 된다는 점입니다.

10번에서 중복체크만 없애는 방식으로 하였습니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
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 StringBuffer sb = new StringBuffer();
    static ArrayList<Integer> ans = new ArrayList<>();
    static Set<ArrayList<Integer>> s = new HashSet<>();
    static int list[];
    static int N, M;
 
    static void func(int cnt) {
        if (cnt == M) {
            if (s.contains(ans))
                return;
 
            s.add(ans);
            for (int i = 0; i < M; i++) {
                sb.append(ans.get(i) + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = 0; i < N; i++) {
            int x = list[i];
 
            ans.add(x);
            func(cnt + 1);
            ans.remove(cnt);
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new int[N];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
 
        Arrays.sort(list);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(0);
        System.out.println(sb.toString());
    }
}
cs

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

boj 9202 Boggle  (0) 2021.02.02
boj 15666 N과 M (12)  (0) 2021.01.31
boj 15664 N과 M (10)  (0) 2021.01.30
boj 15663 N과 M (9)  (0) 2021.01.28
boj 15657 N과 M (8)  (0) 2021.01.27

www.acmicpc.net/problem/15664

 

15664번: N과 M (10)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

N과M 10번째 문제입니다.

9번째 문제와 다른점은 비내림차순 수열을 출력해야합니다. 그 외에는 똑같습니다.

 

9번은 비내림차순이라는 조건이 없어서 재귀돌릴 때 인덱스 관리를 안했지만

이 문제는 비내림차순이라는 조건이 있어서 이전에 골랐던 인덱스 관리를 해야합니다.

i번을 골랐다면 i + 1을 매개변수로 넘겨줍니다.

 

중복되는 수열을 출력하면 안되기때문에 set을 사용하였습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
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 StringBuffer sb = new StringBuffer();
    static boolean visit[];
    static ArrayList<Integer> ans = new ArrayList<>();
    static Set<ArrayList<Integer> > s = new HashSet<>();
    static int list[];
    static int N, M;
 
    static void func(int idx, int cnt) {
        if (cnt == M) {
            if(s.contains(ans))
                return;
            
            s.add(ans);
            for (int i = 0; i < M; i++) {
                sb.append(ans.get(i) + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = idx; i < N; i++) {
            int x = list[i];
 
            if (visit[i])
                continue;
 
            visit[i] = true;
            ans.add(x);
            func(i + 1, cnt + 1);
            ans.remove(cnt);
            visit[i] = false;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new int[N];
        visit = new boolean[N];
        
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
 
        Arrays.sort(list);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(00);
        System.out.println(sb.toString());
    }
}
cs

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

boj 15666 N과 M (12)  (0) 2021.01.31
boj 15665 N과 M (11)  (0) 2021.01.30
boj 15663 N과 M (9)  (0) 2021.01.28
boj 15657 N과 M (8)  (0) 2021.01.27
boj 15656 N과 M (7)  (0) 2021.01.27

www.acmicpc.net/problem/15663

 

15663번: N과 M (9)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

N과M 9번째 문제입니다.

 

다른 문제들과 다른 점은 배열에 중복되는 숫자가 포함되어 주어진다는 것입니다.

 

결과를 출력하였을 때 중복 값을 제외하고 출력해야해서 Set에 ArrayList를 넣어 중복체크를 하였습니다.

 

수열은 오름차순으로 이루어져야한다는 말이 없으니 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
55
56
57
58
59
60
61
62
63
64
65
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
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 StringBuffer sb = new StringBuffer();
    static ArrayList<Integer> list, ans;
    static int N, M;
    static boolean visit[];
    static Set<ArrayList<Integer>> s = new HashSet<>();
 
    static void dfs(int cnt) {
        if (cnt == M) {
            if (s.contains(ans))
                return;
 
            s.add(ans);
            for (int i = 0; i < ans.size(); i++) {
                sb.append(ans.get(i) + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = 0; i < N; i++) {
            if (visit[i])
                continue;
 
            int x = list.get(i);
 
            visit[i] = true;
            ans.add(x);
            dfs(cnt + 1);
            ans.remove(cnt);
            visit[i] = false;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new ArrayList<>();
        ans = new ArrayList<>();
        visit = new boolean[N];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list.add(Integer.parseInt(st.nextToken()));
        }
        Collections.sort(list);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        dfs(0);
        System.out.println(sb.toString());
    }
}
cs

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

boj 15665 N과 M (11)  (0) 2021.01.30
boj 15664 N과 M (10)  (0) 2021.01.30
boj 15657 N과 M (8)  (0) 2021.01.27
boj 15656 N과 M (7)  (0) 2021.01.27
boj 15655 N과 M (6)  (0) 2021.01.27

www.acmicpc.net/problem/15657

 

15657번: N과 M (8)

N개의 자연수와 자연수 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오. N개의 자연수는 모두 다른 수이다. N개의 자연수 중에서 M개를 고른 수열

www.acmicpc.net

N과M 8번째 문제입니다.

 

배열에서 M개를 고른 수열을 구하는데

같은 수를 여러번 사용해도되며 비내림차순으로 이루어진 수열이어야 합니다.

 

중복이 가능하기 때문에 방문체크는 하지않고,

비내림차순이므로 dfs를 돌리는 과정에서 ans에 추가했던 인덱스를 +1하지 않고 그대로 재귀로 보내버리는 식으로 하였습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
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 ArrayList<Integer> list, ans;
    static int N, M;
 
    static void dfs(int idx, int cnt) {
        if (cnt == M) {
            for (int i = 0; i < ans.size(); i++) {
                sb.append(ans.get(i) + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = idx; i < N; i++) {
            int x = list.get(i);
 
            ans.add(x);
            dfs(i, cnt + 1);
            ans.remove(cnt);
        }
    }
 
    static void input() throws Exception {
        list = new ArrayList<>();
        ans = new ArrayList<>();
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list.add(Integer.parseInt(st.nextToken()));
        }
        Collections.sort(list);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        dfs(00);
        System.out.println(sb.toString());
    }
}
cs

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

boj 15664 N과 M (10)  (0) 2021.01.30
boj 15663 N과 M (9)  (0) 2021.01.28
boj 15656 N과 M (7)  (0) 2021.01.27
boj 15655 N과 M (6)  (0) 2021.01.27
boj 15654 N과 M (5)  (0) 2021.01.27

www.acmicpc.net/problem/15656

 

15656번: N과 M (7)

N개의 자연수와 자연수 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오. N개의 자연수는 모두 다른 수이다. N개의 자연수 중에서 M개를 고른 수열

www.acmicpc.net

N과M 7번째 문제입니다.

이번 문제는 5번째 문제처럼 주어진 배열에서 M개를 고르는데, 같은 수를 골라도 되는 문제입니다.

 

중복이 가능하기 때문에 방문체크는 하지않고 0~N-1까지 접근하시면 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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 StringBuffer sb = new StringBuffer();
    static int list[], ans[];
    static int N, M;
 
    static void dfs(int cnt) {
        if (cnt == M) {
            for (int i = 0; i < M; i++) {
                sb.append(ans[i] + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = 0; i < N; i++) {
            int x = list[i];
 
            ans[cnt] = x;
            dfs(cnt + 1);
            ans[cnt] = 0;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new int[N];
        ans = new int[M];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
        Arrays.sort(list);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        dfs(0);
        System.out.println(sb.toString());
    }
}
cs

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

boj 15663 N과 M (9)  (0) 2021.01.28
boj 15657 N과 M (8)  (0) 2021.01.27
boj 15655 N과 M (6)  (0) 2021.01.27
boj 15654 N과 M (5)  (0) 2021.01.27
boj 15652 N 과 M (4)  (0) 2021.01.26

+ Recent posts