본문 바로가기
Baekjoon/[6] 백트래킹

[백준] 5568번 카드 놓기 JAVA (자바) 풀이

by Poorm 푸름 2024. 5. 3.

문제 5568  (백트래킹)

 

 : 카드 n장 (4 ≤ n ≤ 10)
   각 카드 1이상 99이하의 정수

 : 카드 k장 (2 ≤ k ≤ 4) 선택 후 가로로 나란히 정수를 만들기

 : 만들 수 있는 정수는 모두 몇 가지일까?

 

[입력]

 

: 첫째 줄에 n, 둘째 줄에 k
: 셋째 줄 ~ n개 줄에는 카드에 적혀있는 수

 

[출력]

 

: 만들 수 있는 카드 개수

 

 

[과정]

 

조합 중복 방지 vs 결과 중복 방지

  • 조합 중복 (백트래킹으로 해결)

    조합 중복 방지란 (1,1)이 아닌 (1,2)처럼 서로 다른 조합을 말한다 

  • 결과 중복 (hashset으로 해결)

    결과 중복 방지란 (1,2)와 (2,1)을 같은 값으로 처리하는 것을 말한다 
 

 

 [코드]

import java.io.*;
import java.util.*;
public class Main{
    static int N,k,arr[];
    static HashSet<String> card = new HashSet<>(); 
    static boolean visit[];
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N=Integer.parseInt(br.readLine());
        k=Integer.parseInt(br.readLine());
        arr=new int[N];
        visit=new boolean[N];
       
        
        for(int i=0; i<N; i++){
            arr[i]=Integer.parseInt(br.readLine());
        }
        
        back(0,"");
        System.out.println(card.size());
        
    }
    
    public static void back(int depth, String a){
        if(depth==k){
           card.add(a);
            return;
        }
        
        for(int i=0; i<N; i++){
            if(!visit[i]){
                visit[i]=true;
                back(depth+1,a+arr[i]);
                visit[i]=false;
            }
        }
    }
}

 

 [해설]
     

 :  static int N,k,arr[];  입력받기
    static HashSet<String> card = new HashSet<>();  결과 중복 방지
    static boolean visit[];  방문기록

 

 :  N=Integer.parseInt(br.readLine());  첫번째줄
    k=Integer.parseInt(br.readLine());  두번째줄
    arr=new int[N];  세번째줄
    visit=new boolean[N];  방문기록
       
        
 :  for(int i=0; i<N; i++){
            arr[i]=Integer.parseInt(br.readLine());  세번째줄 차례로 입력
    }
        
        back(0,"");  백트래킹 시작
        System.out.println(card.size());  hashset 크기 출력
        
    }
    
 : public static void back(int depth, String a){  깊이, 문자로 숫자 붙이기
        if(depth==k){  깊이가 k만큼 되면 종료
           card.add(a);  hashset에 만든 숫자배열 추가
           return;
        }
        
        for(int i=0; i<N; i++){ 
            if(!visit[i]){  방문하지 않은 것들만
                visit[i]=true;  방문처리
                back(depth+1,a+arr[i]);  층 바꿔서 다음 인덱스에 들어올 숫자 백트래킹 반복
                visit[i]=false;
            }
        }
    }


 

 

이제 풀어보러 갈께요 :)

 

 

 

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

 

5568번: 카드 놓기

예제 1의 경우 상근이는 11, 12, 21, 112, 121, 122, 212를 만들 수 있다.

www.acmicpc.net



 

* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *