2023. 2. 11. 02:36ㆍ문제풀이/백트래킹
문제
https://www.acmicpc.net/problem/2529
2529번: 부등호
두 종류의 부등호 기호 ‘<’와 ‘>’가 k개 나열된 순서열 A가 있다. 우리는 이 부등호 기호 앞뒤에 서로 다른 한 자릿수 숫자를 넣어서 모든 부등호 관계를 만족시키려고 한다. 예를 들어, 제시
www.acmicpc.net

풀이
백트래킹 방법으로 문제를 해결할 것이다.
백트래킹 방법은 가지를 탐색하다가 옳지 않으면 바로 다른 가지로 넘어간다.
이 문제에서는 첫번째 자리의 수부터 k+1번째 자리의 수까지 추가해나가며 탐색한다.
탐색 중에 j번째 자리에 넣을 수가 이전 수와의 부등호 조건에 맞지 않으면(ex- 부등호가 <인데 이전 수보다 작은 경우), 바로 다음 경우로 넘어간다.
만약, j번째 자리에 어떤 수를 넣더라도 부등호 조건에 맞지 않으면, j-1번째 자리의 수를 바꾸게 된다.
백트래킹으로 탐색하는 과정을 코드로 구현해보면 다음과 같다.
public static void findResult(int idx){
//모든 자리의 수가 조건을 만족하는 정수를 찾으면 그 정수를 result에 저장한다.
if(idx == n+1){
StringBuilder sb = new StringBuilder();
for(int i : temp)
sb.append(i);
result.add(sb.toString());
return;
}
for(int i = 0; i<=9; i++){
//이전 자리의 수에서 i가 없어야 하며, 부등호 조건에 만족해야만 한다
if(!temp.contains(i) && check(i)){
temp.add(i);
findResult(idx+1);
temp.remove(temp.size()-1);
}
}
}
부등호 조건에 만족하는지 확인하는 메서드는 다음과 같이 구현한다.
private static boolean check(int k){
//0번째 자리의 수를 찾는다면, 부등호가 없으므로 모두 가능하다
if(temp.isEmpty()) return true;
int last = temp.get(temp.size()-1);
String checkSign = sign[temp.size()-1];
//부등호를 확인하고, 이전 수와 넣으려는 수 k가 부등호 조건을 만족하는지 확인한다
if(checkSign.equals("<")){
if(last>k) return false;
}else if(checkSign.equals(">")){
if(last<k) return false;
}
return true;
}
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
static int n;
static String[] sign;
static List<Integer> temp = new ArrayList<>();
static List<String> result = new ArrayList<>();
public static void findResult(int idx){
if(idx == n+1){
StringBuilder sb = new StringBuilder();
for(int i : temp)
sb.append(i);
result.add(sb.toString());
return;
}
for(int i = 0; i<=9; i++){
if(!temp.contains(i) && check(i)){
temp.add(i);
findResult(idx+1);
temp.remove(temp.size()-1);
}
}
}
private static boolean check(int k){
if(temp.isEmpty()) return true;
int last = temp.get(temp.size()-1);
String checkSign = sign[temp.size()-1];
if(checkSign.equals("<")){
if(last>k) return false;
}else if(checkSign.equals(">")){
if(last<k) return false;
}
return true;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
sign = new String[n];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i = 0; i<n; i++){
sign[i] = st.nextToken();
}
findResult(0);
System.out.println(result.get(result.size()-1));
System.out.println(result.get(0));
}
}
다른 방법
이 문제는 순차탐색의 브루트포스 방법으로도 해결할 수 있다. 이전, 다음 순열을 구해 순차 탐색하는 풀이는 아래에서 확인할 수 있다.
https://sy-zoze.tistory.com/17
[백준/JAVA] 2529번 : 부등호(BruteFroce, 순열)
문제 https://www.acmicpc.net/problem/2529 2529번: 부등호 두 종류의 부등호 기호 ‘’가 k개 나열된 순서열 A가 있다. 우리는 이 부등호 기호 앞뒤에 서로 다른 한 자릿수 숫자를 넣어서 모든 부등호 관계
sy-zoze.tistory.com
'문제풀이 > 백트래킹' 카테고리의 다른 글
[백준/JAVA] 9663번 : N-Queen(BackTracking, 백트래킹) (0) | 2023.02.12 |
---|