• 문제 링크
16943번: 숫자 재배치
두 정수 A와 B가 있을 때, A에 포함된 숫자의 순서를 섞어서 새로운 수 C를 만들려고 한다. 즉, C는 A의 순열 중 하나가 되어야 한다. 가능한 C 중에서 B보다 작으면서, 가장 큰 값을 구해보자. C는 0
www.acmicpc.net
• 풀이 과정
입력받은 문자열 a를 순열으로써 charAt() 으로 인덱스를 탐색하고, boolean 배열을 활용한 백트래킹으로 구한다.
이때 문제에 주어진 조건 상 구해진 순열이 0 으로 시작하면 안되고 b 보다 작거나 같아야 하므로
순열의 하나의 경우의 수를 c 이고 탐색을 수행할 반복문의 인덱스를 i 라고 할 때,
현재 문자열 a 에서 탐색한 숫자가 0 이거나 (a.charAt(i) - '0' == 0),
구해진 순열이 b 보다 클 경우 (Integer.parseInt(c + a.charAt(i)) > b) 해당 인덱스를 건너뛴다.
이러한 조건에 의해 구해진 순열과 현재까지 구해진 순열 중 큰 수를 res 변수에 갱신시켜 정답으로써 출력하며
만약 res 변수가 갱신된 적이 없다면 b 보다 작은 c 가 없으므로 기본값 -1 을 출력한다.
• 풀이 코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
static String a;
static int b;
static int res = -1;
static boolean[] visit;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
a = st.nextToken();
b = Integer.parseInt(st.nextToken());
visit = new boolean[a.length()];
recur("", 0);
bw.write(res + "\n");
bw.flush();
}
private static void recur(String c, int depth) {
if (depth == a.length()) {
res = Math.max(res, Integer.parseInt(c));
return;
}
for (int i = 0; i < a.length(); i++) {
if (visit[i])
continue;
if (a.charAt(i) - '0' == 0 && depth == 0)
continue;
if (Integer.parseInt(c + a.charAt(i)) > b)
continue;
visit[i] = true;
recur(c + a.charAt(i), depth + 1);
visit[i] = false;
}
}
}
'Problem Solving > Baekjoon' 카테고리의 다른 글
[백준] 16924 십자가 찾기 - Brute Force / Java (0) | 2022.08.03 |
---|---|
[백준] 2580 스도쿠 - Backtracking / Java (0) | 2022.08.02 |
[백준] 16922 로마 숫자 만들기 - Backtracking / Java (0) | 2022.07.31 |
[백준] 1744 수 묶기 - Greedy / Java (0) | 2022.07.30 |
[백준] 12904 A와 B - Greedy / Java (0) | 2022.07.29 |
댓글