코딍코딍
코딩기록
코딍코딍
전체 방문자
오늘
어제
  • 분류 전체보기 (271)
    • 개발 (2)
    • Java (1)
    • 스프링 (28)
    • JPA (11)
    • Git (3)
    • 알고리즘 (160)
      • 백준 (132)
      • 프로그래머스 (8)
      • SWEA (20)
    • 토이 프로젝트 (14)
      • 간단한 Springboot CRUD (1)
      • 게시판 프로젝트 (13)
    • 알고리즘 개념정리 (8)
    • 오류 해결 (13)
    • 보류 (0)
    • AWS (5)
    • 트러블 슈팅 (0)
    • 회고 (3)
    • CS (4)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

최근 글

티스토리

hELLO · Designed By 정상우.
코딍코딍

코딩기록

알고리즘/백준

15663번 : N과 M (9)

2023. 9. 14. 20:47

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

 

15663번: N과 M (9)

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

www.acmicpc.net

 

문제

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

  • N개의 자연수 중에서 M개를 고른 수열

 

입력

첫째 줄에 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)

둘째 줄에 N개의 수가 주어진다. 입력으로 주어지는 수는 10,000보다 작거나 같은 자연수이다.

 

출력

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

수열은 사전 순으로 증가하는 순서로 출력해야 한다.

 


소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    static int n;
    static int m;
    static StringBuilder sb;
    static boolean[] used;
    static int[] arr;
    static HashSet<String> set = new HashSet<>();

    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());
        used = new boolean[n + 1];
        sb = new StringBuilder();
        arr = new int[n + 1];

        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= n; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        Arrays.sort(arr);

        backtrack(0, "");
        System.out.println(sb);
    }

    static void backtrack(int cnt, String s) {
        if (cnt == m && !set.contains(s)) {
            set.add(s);
            sb.append(s.trim() + "\n");
            return;
        }

        for (int i = 1; i <= n; i++) {
            if(!used[i]) {
                used[i] = true;
                backtrack(cnt + 1, s + " " + arr[i]);
                used[i] = false;
            }
        }
    }
}

 

해결방법

기본적인 백트래킹 문제이고 HashSet을 사용하여 중복되는 수열이 생기지 않도록 해야한다.

처음에 HashSet에 이미 사용한 수를 넣는 방식으로 구현했는데 해결하지 못 했다.

그래서 생각을 더 해보았는데 수열(문자열)만 비교하면 되니까 HashSet에 수열을 넣으면 매우 간단하게 해결된다.

 

'알고리즘 > 백준' 카테고리의 다른 글

6603번 : 로또  (0) 2023.09.17
1759번 : 암호 만들기  (0) 2023.09.17
2457번 : 공주님의 정원  (0) 2023.09.13
1744번 : 수 묶기  (0) 2023.09.12
11000번 : 강의실 배정  (0) 2023.09.11
    '알고리즘/백준' 카테고리의 다른 글
    • 6603번 : 로또
    • 1759번 : 암호 만들기
    • 2457번 : 공주님의 정원
    • 1744번 : 수 묶기
    코딍코딍
    코딍코딍
    ㅎ2

    티스토리툴바