๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Algorithm

[Java] 15664๋ฒˆ: N๊ณผ M(10)

๐ŸŒŽ Link : https://www.acmicpc.net/problem/15664

 

15664๋ฒˆ: N๊ณผ M (10)

ํ•œ ์ค„์— ํ•˜๋‚˜์”ฉ ๋ฌธ์ œ์˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์ˆ˜์—ด์„ ์ถœ๋ ฅํ•œ๋‹ค. ์ค‘๋ณต๋˜๋Š” ์ˆ˜์—ด์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์ถœ๋ ฅํ•˜๋ฉด ์•ˆ๋˜๋ฉฐ, ๊ฐ ์ˆ˜์—ด์€ ๊ณต๋ฐฑ์œผ๋กœ ๊ตฌ๋ถ„ํ•ด์„œ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. ์ˆ˜์—ด์€ ์‚ฌ์ „ ์ˆœ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋Š” ์ˆœ์„œ๋กœ ์ถœ๋ ฅํ•ด

www.acmicpc.net


๐Ÿ’ก ์ ‘๊ทผ ๋ฐฉ๋ฒ•

1. ๋ฌธ์ œ ์ดํ•ด

๊ธฐ์กด N๊ณผ M์‹œ๋ฆฌ์ฆˆ ๋ฌธ์ œ๋ฅผ ํ’€๋ฉด์„œ ์–ด๋Š ์ •๋„ ๋ฐฑํŠธ๋ ˆํ‚น์— ๋Œ€ํ•œ ๊ฐ์„ ์ตํžˆ๊ณ  ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฌธ์ œ์˜ ํŠน์ง•์ด ๋ช‡ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

  1. ์ค‘๋ณต๋œ ์ˆ˜์—ด์€ ์ถœ๋ ฅํ•˜์ง€ ๋งˆ๋ผ
  2. ์ˆ˜์—ด์€ ์‚ฌ์ „์ˆœ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ผ
  3. ๊ณ ๋ฅธ ์ˆ˜์—ด์€ ๋น„๋‚ด๋ฆผ์ฐจ์ˆœ์ด์–ด์•ผ ํ•œ๋‹ค(์˜ค๋ฆ„์ฐจ์ˆœ, ๊ฐ’์ด ๊ฐ™์•„๋„ ๋œ๋‹ค)

2. ๋ฌธ์ œ ํ’€์ด

  • ์ค‘๋ณต๋œ ์ˆ˜์—ด์€ ์ถœ๋ ฅํ•˜์ง€ ๋งˆ๋ผ
    • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ž๋ฃŒ๊ตฌ์กฐ Set์„ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ด๋‹ค. ํ•˜์ง€๋งŒ Set์˜ ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ํฌ๊ฒŒ ์„ธ๊ฐ€์ง€๋กœ ๋‚˜๋‰˜๋Š”๋ฐ ๊ฐ์ž์˜ ํŠน์ง•์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•Œ๋งž์€ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค. ๋‚˜๋Š” ์ค‘๋ณต์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ณ  ์ž…๋ ฅํ•œ ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅ์„ ํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— LinkedHashSet์„ ์‚ฌ์šฉํ•œ๋‹ค.
    • HashSet : ์ˆœ์„œ๊ฐ’์„ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.
    • TreeSet : ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋˜ ์ €์žฅ๋œ๋‹ค.
    • LinkedHashSet : ์ถ”๊ฐ€๋œ ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅ์ด ๋œ๋‹ค.
  • ์ˆ˜์—ด์€ ์‚ฌ์ „์ˆœ์œผ๋กœ ์ถœ๋ ฅํ•ด๋ผ
    • ์ •๋ ฌ์„ ํ•ด์„œ ํ•ด๊ฒฐํ•œ๋‹ค.
  • ๊ณ ๋ฅธ ์ˆ˜์—ด์€ ๋น„๋‚ด๋ฆผ์ฐจ์ˆœ์ด์–ด์•ผ ํ•œ๋‹ค(์˜ค๋ฆ„์ฐจ์ˆœ, ๊ฐ’์ด ๊ฐ™์•„๋„ ๋œ๋‹ค)
    • int []์„ ๋ณต์‚ฌํ•ด์„œ ์ •๋ ฌ ํ›„ ๊ธฐ์กด์˜ ๊ฐ’์ด ๋‹ค๋ฅผ ๊ฒฝ์šฐ false ๊ฐ™์„ ๊ฒฝ์šฐ true๋กœ ์ฒ˜๋ฆฌํ•ด์„œ ํ•ด๊ฒฐํ•œ๋‹ค.

๐Ÿ— ํ’€์ด ์ฝ”๋“œ

1์ฐจ ํ’€์ด์ฝ”๋“œ

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.StringTokenizer;

public class Main {

    static int N, M;
    static boolean[] isVisited;
    static int[] temp, store;
    static LinkedHashSet<String> answer;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        answer = new LinkedHashSet<>();
        temp = new int[M];
        isVisited = new boolean[N];
        store = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        Arrays.sort(store);

        backtracking(0);

        answer.forEach(System.out::println);
    }

    private static void backtracking(int depth) {
        if (depth == M) {
            if (!validate()) return;
            findAnswer();
            return;
        }

        for (int i = 0; i < N; i++) {
            if (!isVisited[i]) {
                temp[depth] = store[i];
                isVisited[i] = true;
                backtracking(depth + 1);
                isVisited[i] = false;
            }
        }
    }

    private static void findAnswer() {
        StringBuilder sb = new StringBuilder();
        for (int t : temp) {
            sb.append(t).append(" ");
        }

        answer.add(sb.toString());
    }

    private static boolean validate() {
        int[] copyTemp = temp.clone();
        Arrays.sort(copyTemp);

        return Arrays.equals(temp, copyTemp);
    }
}

 

๋ฌธ์ œ๋Š” ํ•ด๊ฒฐํ–ˆ์ง€๋งŒ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์€ ์–ด๋–ป๊ฒŒ ํ’€์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋‹ค๊ฐ€ ์ƒ‰๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์•Œ๊ฒŒ ๋๋‹ค. ์šฐ์„  ๋‚˜๋Š” ๋น„๋‚ด๋ฆผ์ฐจ์ˆœ์„ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด Arrays.equals()๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„์„ ํ–ˆ์ง€๋งŒ ๊ธฐ์กด์— Arrays.sort(stroe)๋กœ ์ •๋ ฌ์„ ํ•ด์ค€ ์ƒํƒœ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์—ˆ๋‹ค. ๋˜ํ•œ ๊ฐ™์€ ์ธ๋ฑ์Šค์˜ ์ ‘๊ทผ์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ isVisited []๋ฅผ ํ™œ์šฉํ–ˆ์ง€๋งŒ ์ด ๋ถ€๋ถ„๋„ ํ•จ๊ป˜ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด 1, 4, 7, 9๋ฉด ์ •๋‹ต์€ (1-4, 1-7, 1-9, 4-7, 4-9, 7-9)๋กœ ์ถœ๋ ฅ์ด ๋œ๋‹ค. ์—ฌ๊ธฐ์„œ ํฌ์ธํŠธ๊ฐ€ 7(index 2)-1(index 0)๊ณผ ๊ฐ™์ด ์•ˆ ๋‚˜์˜ค๋ฉด ๋œ๋‹ค. backtracking์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ธฐ์กด depth์— start๋ฅผ ์ถ”๊ฐ€๋ฅผ ํ•ด์ค˜์„œ ์ด๋ฅผ for ๋ฐ˜๋ณต๋ฌธ์—์„œ ์‹œ์ž‘ ์ธ๋ฑ์Šค๋ฅผ ์„ค์ •์„ ํ•ด์ฃผ๋ฉด ์œ„์™€ ๊ฐ™์€ ํƒ์ƒ‰์€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. ๋˜ํ•œ ๊ธฐ์กด ์ •๋ ฌ์„ ํ•ด์คฌ๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ๋น„๋‚ด๋ฆผ์ฐจ์ˆœ์„ ๊ฒ€์ฆํ•  ํ•„์š”๋„ ์—†์–ด์ง„๋‹ค.

2์ฐจ ํ’€์ด์ฝ”๋“œ

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.StringTokenizer;

public class Main {

    static int N, M;
    static int[] store, temp;
    static LinkedHashSet<String> answer;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        store = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        Arrays.sort(store);

        temp = new int[M];
        answer = new LinkedHashSet<>();

        backtrack(0, 0);

        answer.forEach(System.out::println);
    }

    private static void backtrack(int depth, int start) {
        if (depth == M) {
            addCombination();
            return;
        }

        for (int i = start; i < N; i++) {
            temp[depth] = store[i];
            backtrack(depth + 1, i + 1);
        }
    }

    private static void addCombination() {
        StringBuilder sb = new StringBuilder();
        for (int number : temp) {
            sb.append(number).append(" ");
        }
        answer.add(sb.toString());
    }
}