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

 

[난이도]

- Silver 2

 

[알고리즘]

- 백트래킹

 

[코드]

import java.io.*;
import java.util.*;

public class Main {
    static int N, answer = Integer.MAX_VALUE;
    static int[][] map;
    static boolean[] visited;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st;

        N = Integer.parseInt(br.readLine());
        map = new int[N][N];
        visited = new boolean[N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        for (int i = 0; i < N; i++) {
            visited[i] = true;
            backTracking(i, i, 0, 0);
        }
        System.out.println(answer);
    }

    /**
     * @param start : 메서드 실행 전 위에서 정해줌
     * @param now : 현재 내가 위치한 도시
     * @param sum : 현재위치한 도시까지 사용한 비용
     * @param depth
     */
    static void backTracking(int start, int now, int sum, int depth) {
        if (depth == N - 1) { // 모든 도시를 모두 방문한 경우, N-1인 이유는 백트래킹 메서드를 실행하기 전에 이미 방문함
            if (map[now][start] != 0) { // 마지막 도시에서 처음 도시로 가는 비용 더하기
                sum += map[now][start];
                answer = Math.min(answer, sum); // 최종적으로 나온 비용
            }
            return;
        }
        for (int i = 0; i < N; i++) {
            if (!visited[i]) { // 방문하지 않은 도시일경우
                if (map[now][i] != 0) { // 갈수 있는 도시일경우
                    visited[i] = true; // 방문했다면 true
                    backTracking(start, i, sum + map[now][i], depth + 1);
                    visited[i] = false; // 방문이 끝나면 false
                }
            }
        }
    }
}

[풀이]

 

시작하는 도시가 1번도시로 고정이 아닌 어느도시에서 시작하든 최소비용을 찾는것이기 때문에 N번 반복한다.

        for (int i = 0; i < N; i++) {
            visited[i] = true;
            backTracking(i, i, 0, 0);
        }

 

 

백트래킹 메서드의 매개변수 start 는 순회를 시작한 도시의 위치로 메서드를 실행할 때 정해진다.

매개변수 now는 현재 내가 위치한 도시의 위치를 뜻한다. 

매개변수 sum은 현재 내가 now에 올때까지 사용한 비용을 뜻한다.

매개변수 depth는 모든도시를 순회했는지 체크한다.

 

 

for문을 돌며 방문하지 않은 도시이며 map[i][j]가 0이 아닌도시(방문할 수 있는 도시) 라면 백트래킹을 재귀적으로 수행한다.

이때 넣어주어야 하는 매개변수들은 순회를 시작한 도시 start, 다음 방문할 도시 i, 현재까지 사용한 비용(sum) + 현재 위치에서 i까지 가는 비용(map[now][i]), depth + 1이다.

        for (int i = 0; i < N; i++) {
            if (!visited[i]) { // 방문하지 않은 도시일경우
                if (map[now][i] != 0) { // 갈수 있는 도시일경우
                    visited[i] = true; // 방문했다면 true
                    backTracking(start, i, sum + map[now][i], depth + 1);
                    visited[i] = false; // 방문이 끝나면 false
                }
            }
        }

 

 

depth 가 N-1이 되면 모든도시를 방문한 것이다. depth가 N이아닌 N-1인 이유는 순회를 시작한 도시는 메서드 실행전 체크하기 때문이다.

depth가 N-1이 되었다면 마지막 도착한 도시에서 순회를 시작한 도시로 돌아와야하기 때문에 map[now][start] != 0 이라면

sum += map[now][start]를 해주어 마지막 비용을 추가해준다.

        if (depth == N - 1) { // 모든 도시를 모두 방문한 경우, N-1인 이유는 백트래킹 메서드를 실행하기 전에 이미 방문함
            if (map[now][start] != 0) { // 마지막 도시에서 처음 도시로 가는 비용 더하기
                sum += map[now][start];
                answer = Math.min(answer, sum); // 최종적으로 나온 비용
            }
            return;
        }

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

 

 

 

[난이도]

- Silver 2

 

[알고리즘]

- 백트래킹

 

[코드]

import java.io.*;
import java.util.*;

public class Main {
    static int k;
    static int[] arr, list;
    static boolean[] checked;
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        while (true) {
            st = new StringTokenizer(br.readLine(), " ");
            k = Integer.parseInt(st.nextToken());
            if (k == 0) { // 0일경우 종료
                break;
            }
            arr = new int[k];
            list = new int[6];
            checked = new boolean[k];
            for (int i = 0; i < k; i++) {
                arr[i] = Integer.parseInt(st.nextToken());
            }
            backTracking(0, 0);
            bw.write("\n");
        }
        bw.flush();
        bw.close();
        br.close();
    }

    static void backTracking(int depth, int start) throws Exception{
        if (depth == 6) {
            for (int i : list) {
                bw.write(i + " ");
            }
            bw.write("\n");
            return;
        }
        for (int i = start; i < k; i++) { // i 는 start부터 시작
            if (!checked[i]) { // 사용하지 않은 숫자만 허용
                checked[i] = true;
                list[depth] = arr[i];
                backTracking(depth + 1, i + 1); // i+1을 해주어 중복을 막음
                checked[i] = false;
            }
        }
    }
}

[풀이]

1. 입력을 받는다. k가 0일경우 종료한다. 입력받은숫자는 arr 배열에 저장한다.

2. 백트래킹 알고리즘을 수행한다. 매개변수로 depth, start를 받는다. 0, 0부터 시작.

3. for문을 돌며 arr에 담긴 숫자를 list에 담아준다. for문은 i = start부터 시작.

4. 숫자를 list배열에 담아준 후 depth+1, i+1로 재귀적으로 호출해준다.

5. depth가 6일경우 list배열에 담겨있는 숫자를 출력해준다.

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

[난이도]

- Silver 3

 

[알고리즘]

- 백트래킹

 

[코드]

import java.io.*;
import java.util.*;

public class Main {
    static int N, M;
    static boolean[] checked;
    static int[] arr, tmp;
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        checked = new boolean[N];
        arr = new int[N];
        tmp = new int[N];

        st = new StringTokenizer(br.readLine(), " ");
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        Arrays.sort(arr); // 오름차순 정렬
        backTracking(0, 0);
        bw.flush();
    }

    static void backTracking(int depth, int start) throws Exception {
        if (depth == M) { // depth 가 M이 될때까지 실행
            for (int i = 0; i < M; i++) {
                bw.write(tmp[i] + " ");
            }
            bw.write("\n");
            return;
        }

        for (int i = start; i < N; i++) {
            tmp[depth] = arr[i];
            backTracking(depth + 1, i);
        }
    }
}

[풀이]

사용한 숫자를 중복해서 사용하기 위해 boolean 배열을 사용하지 않는다.

비내림차순을 만족하기위해 매개변수를 depth 이외에 하나를 추가해준다. 매개변수는 i로 준다.

'코딩테스트' 카테고리의 다른 글

백준 10971: 외판원 순회 2 [JAVA]  (0) 2024.05.08
백준 6603: 로또 [JAVA]  (0) 2024.05.08
백준 15656: N과 M (7) [JAVA]  (0) 2024.05.08
백준 15655: N과 M (6) [JAVA]  (0) 2024.05.08
백준 15654: N과 M (5) [JAVA]  (0) 2024.05.08

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

 

[난이도]

- Silver 3

 

[알고리즘]

- 백트래킹

 

[코드]

import java.io.*;
import java.util.*;

public class Main {
    static int N, M;
    static boolean[] checked;
    static int[] arr, tmp;
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        checked = new boolean[N];
        arr = new int[N];
        tmp = new int[N];

        st = new StringTokenizer(br.readLine(), " ");
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        Arrays.sort(arr); // 오름차순 정렬
        backTracking(0);
        bw.flush();
    }

    static void backTracking(int depth) throws Exception {
        if (depth == M) { // depth 가 M이 될때까지 실행
            for (int i = 0; i < M; i++) {
                bw.write(tmp[i] + " ");
            }
            bw.write("\n");
            return;
        }

        for (int i = 0; i < N; i++) {
            tmp[depth] = arr[i];
            backTracking(depth + 1);
        }
    }
}

[풀이]

boolean 배열로 사용한 숫자를 체크하지 않고 중복도 허용하게 한다.

'코딩테스트' 카테고리의 다른 글

백준 6603: 로또 [JAVA]  (0) 2024.05.08
백준 15657: N과 M (8) [JAVA]  (0) 2024.05.08
백준 15655: N과 M (6) [JAVA]  (0) 2024.05.08
백준 15654: N과 M (5) [JAVA]  (0) 2024.05.08
백준 15652: N과 M (4) [JAVA]  (0) 2024.05.07

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

[난이도]

- Silver 3

 

[알고리즘]

- 백트래킹

 

[코드]

import java.io.*;
import java.util.*;

public class Main {
    static int N, M;
    static boolean[] checked;
    static int[] arr, tmp;
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        checked = new boolean[N];
        arr = new int[N];
        tmp = new int[N];

        st = new StringTokenizer(br.readLine(), " ");
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        Arrays.sort(arr); // 오름차순 정렬
        backTracking(0, 0);
        bw.flush();
    }

    static void backTracking(int depth, int start) throws Exception {
        if (depth == M) { // depth 가 M이 될때까지 실행
            for (int i = 0; i < M; i++) {
                bw.write(tmp[i] + " ");
            }
            bw.write("\n");
            return;
        }
        for (int i = start; i < N; i++) {
            if (!checked[i]) { // 사용한 숫자 체크
                checked[i] = true;
                tmp[depth] = arr[i];
                backTracking(depth + 1, i);
                checked[i] = false; // 완전탐색을 위해 사용한 숫자는 false
            }
        }
    }
}

[풀이]

매개변수로 depth 말고 start 변수도 추가했다. start 매개변수는 i 로 재귀한다.

 

'코딩테스트' 카테고리의 다른 글

백준 15657: N과 M (8) [JAVA]  (0) 2024.05.08
백준 15656: N과 M (7) [JAVA]  (0) 2024.05.08
백준 15654: N과 M (5) [JAVA]  (0) 2024.05.08
백준 15652: N과 M (4) [JAVA]  (0) 2024.05.07
백준 15651: N과 M (3) [JAVA]  (0) 2024.05.07

+ Recent posts