https://www.acmicpc.net/problem/2529
두 종류의 부등호 기호 ‘<’와 ‘>’가 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의 범위는 2 ≤ k ≤ 9
첫 자리가 0인 경우도 정수에 포함되어야 한다.
모든 입력에 답은 항상 존재하며 출력 정수는 하나의 문자열이 되도록 해야 한다.
DFS로 탐색한다. 이전 숫자와 해당 차례 부등호를 이용해서 가능 범위의 숫자만 추가로 탐색한다. 이전에 사용한 숫자인지 boolean 배열을 이용해서 체크한다. 숫자 크기가 int 범위를 넘어서므로 long 을 이용한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String[] inequalitySignArr = new String[n];
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
br.close();
for (int i = 0; i < n; i++) {
inequalitySignArr[i] = st.nextToken();
}
solution(inequalitySignArr);
}
private static void solution(String[] inequalitySignArr) {
String[] maxMinArr = new String[] {String.valueOf(Long.MIN_VALUE), String.valueOf(Long.MAX_VALUE)}; //최대, 최소
for (int i = 0; i <= 9; i++) {
boolean[] visited = new boolean[10];
visited[i] = true;
dfs(maxMinArr, inequalitySignArr, visited, 0, String.valueOf(i));
}
System.out.println(maxMinArr[0]);
System.out.println(maxMinArr[1]);
}
private static void dfs(String[] maxMinArr, String[] inequalitySignArr, boolean[] visited, int idx, String result) {
if (idx == inequalitySignArr.length) {
long resultNumber = Long.parseLong(result);
maxMinArr[0] = (Long.parseLong(maxMinArr[0]) < resultNumber) ? result : maxMinArr[0]; //최대
maxMinArr[1] = (Long.parseLong(maxMinArr[1]) > resultNumber) ? result : maxMinArr[1]; //최소
return;
}
int number = Integer.parseInt(String.valueOf(result.charAt(result.length() - 1)));
int[] startEnd = getStartEnd(number, inequalitySignArr[idx]);
for (int i = startEnd[0]; i <= startEnd[1]; i++) {
if (!visited[i]) {
visited[i] = true;
dfs(maxMinArr, inequalitySignArr, visited, idx + 1, result + i);
visited[i] = false;
}
}
}
private static int[] getStartEnd(int number, String inequalitySign) {
if (inequalitySign.equals("<")) {
return new int[] {number + 1, 9};
}
return new int[] {0, number - 1};
}
}