Baekjoon (백준) 2529 번

Park Jae Hong·2022년 4월 8일
0

💻 Beakjoon 2529 번 문제 -Java

문제 설명

두 종류의 부등호 기호 ‘<’와 ‘>’가 k개 나열된 순서열 A가 있다. 우리는 이 부등호 기호 앞뒤에 서로 다른 한 자릿수 숫자를 넣어서 모든 부등호 관계를 만족시키려고 한다. 예를 들어, 제시된 부등호 순서열 A가 다음과 같다고 하자.

A ⇒ < < < > < < > < >

부등호 기호 앞뒤에 넣을 수 있는 숫자는 0부터 9까지의 정수이며 선택된 숫자는 모두 달라야 한다. 아래는 부등호 순서열 A를 만족시키는 한 예이다.

3 < 4 < 5 < 6 > 1 < 2 < 8 > 7 < 9 > 0

이 상황에서 부등호 기호를 제거한 뒤, 숫자를 모두 붙이면 하나의 수를 만들 수 있는데 이 수를 주어진 부등호 관계를 만족시키는 정수라고 한다. 그런데 주어진 부등호 관계를 만족하는 정수는 하나 이상 존재한다. 예를 들어 3456128790 뿐만 아니라 5689023174도 아래와 같이 부등호 관계 A를 만족시킨다.

5 < 6 < 8 < 9 > 0 < 2 < 3 > 1 < 7 > 4

여러분은 제시된 k개의 부등호 순서를 만족하는 (k+1)자리의 정수 중에서 최댓값과 최솟값을 찾아야 한다. 앞서 설명한 대로 각 부등호의 앞뒤에 들어가는 숫자는 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }중에서 선택해야 하며 선택된 숫자는 모두 달라야 한다.

  • 입력
    첫 줄에 부등호 문자의 개수를 나타내는 정수 k가 주어진다. 그 다음 줄에는 k개의 부등호 기호가 하나의 공백을 두고 한 줄에 모두 제시된다. k의 범위는 2 ≤ k ≤ 9 이다.

  • 출력
    여러분은 제시된 부등호 관계를 만족하는 k+1 자리의 최대, 최소 정수를 첫째 줄과 둘째 줄에 각각 출력해야 한다. 단 아래 예(1)과 같이 첫 자리가 0인 경우도 정수에 포함되어야 한다. 모든 입력에 답은 항상 존재하며 출력 정수는 하나의 문자열이 되도록 해야 한다.

접근 방법

백트래킹(Backtracking) 문제의 유형이다. 특정 부등호를 String에 담아 부등호 성립여부를 판단해가며 백트래킹을 하면 된다.


문제 풀이

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class Baek_j_2529 {
    public static int N; // 부등호의 개수
    public static String arr = ""; // 특정 부등호를 담기 위한 변수
    public static boolean vi[]; // 방문 여부
    public static ArrayList result = new ArrayList<>(); // 각 경우의 수를 담기 위한 배열

    public static void main(String[] args) throws IOException{

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        N = Integer.parseInt(br.readLine());

        vi = new boolean[10];

        StringTokenizer st = new StringTokenizer(br.readLine());

        for(int i = 0; i < N; i++){
            arr += st.nextToken();
        }

        bt(0,"");
        Collections.sort(result);

        System.out.println(result.get( result.size() - 1 ));
        System.out.println(result.get(0));

    }

    // 모든 경우의 수를 찾기 위해서 Backtracking
    public static void bt(int cut,String temp){
        //부등호의 개수 보다 숫자가 1개 더 많기 때문에 N+1에서 return
        if(N+1 == cut) {
            result.add(temp);
            return;
        }

        // 가능한 수의 범위 0~9까지
        for(int i = 0; i < 10; i++){
            // cut 즉 길이가 0 이거나 부등호가 성립한다면 Backtracking 진행
            if(cut == 0 || check((char) (i + '0'),temp.charAt(cut-1), arr.charAt(cut-1))){
                if(!vi[i]) {
                    vi[i] = true;
                    bt(cut + 1, temp + Integer.toString(i));
                    vi[i] = false;
                }
            }
        }
    }

    // 부등호가 성립하는 여부에 관한 함수
    public static boolean check(char a, char b,char c){

        if(c == '<'){
            if(a > b) return true;
        }

        if(c == '>'){
            if(a < b) return true;
        }
        return false;
    }
}


💡 문제 해결 과정 느낌점

  • 문제 해결 과정에서 어려운 점은 성립 여부를 백트래킹 함숭 같이 넣으려니 코드가 많이 꼬였다. 그래서 분리해서 코딩하였다.
  • 또한, 처음 부등호를 Stringdp 담을때 초기화를 하지 않아 null값이 들어가있어 계속 오류가 나서 잡는데 상당 시간이 소요 되었다. 앞만 보고 달리지 말고 뒤도 보고 기본부터 다시 한번 다져야겠다.
profile
The people who are crazy enough to think they can change the world are the ones who do. -Steve Jobs-

0개의 댓글

관련 채용 정보