백준 12919번 - A와 B 2

황제연·2024년 11월 5일
0

알고리즘

목록 보기
124/169
post-thumbnail

문제 탐색하기

입력 자료 정리

  1. 입력값은 두줄의 문자열이다
    첫번째는 바꾸기전 초기 문자열이고, 두번째는 바꾼 후 문자열이다

해결방법 추론

  1. 이 문제를 해결하기 위해서는 아이디어가 필요하다
  2. 정방향은 바꾸기전 -> 바꾼 후 문자열로 늘려나가는 방법이고,
    역방향은 바꾼 후 -> 바꾸기전 문자열로 줄여나가는 방법이다
  3. 처음에는 정방향을 선택하여 문제를 해결하였다.
    하지만 이 방법은 시간초과를 발생시켰다
  4. 두번째로 생각한 방법은 역방향이다.
    이 방법을 선택했을 때는 조건을 사용할 수 있어서 문제없이 해결할 수 있었다.
  5. 3~4번에 대해서는 아래에서 자세히 다룰 것이다.
  6. 역방향 방법을 선택했으므로 이제 문자를 줄여나가는 방법을 고안해야한다
  7. 주어진 조건대로 문자를 줄여나가는 방법을 생각하였다
  8. 만약 맨 뒤의 값이 A인 경우, 맨 뒤의 값을 지운 문자열을 백트래킹으로 넘겨준다
  9. 만약 맨 앞의 값이 B인 경우, 맨 앞의 값을 지운 뒤 뒤집어서 문자열을 백트래킹으로 넘겨준다
  10. t가 s보다 길이가 작거나 둘이 같은 문자열일 때 종료시키며,
    만약 두 문자열이 같다면 정답을 위한 작업을 진행하도록 하자
  11. 백트래킹 방법을 선택했을 때, 그리고 역방향으로 문자열을 줄이는 방법을 선택했을 때,
    정방향으로 선택한 것보다 가짓수를 더 줄일 수 있어 시간초과없이 문제를 해결할 수 있을 것이다.

시간복잡도 계산

  1. 정방향으로 했을 때, 시간복잡도는 O(2^(|T|-|S|))으로 계산하였다.
    T와 S를 생각했을 때, 49정도 나올 것이고 2^49면 시간제한을 넘어버린다.
    여기서 역방향으로 한다면 조건에 따라 가짓수가 더 줄어들 것이고,
    문제를 제출했을 때 시간제한을 넘지 않고 해결하는 것을 확인할 수 있다.

사실 시간복잡도 계산이 정확하지는 않고, 직접 틀려가면서 시간초과를 줄여야하기때문에
썩 괜찮은 문제로 보이지는 않는다...

코드 설계하기

입력값 상태관리

  1. 입력값은 문자열로 관리해준다. s, t 문자열 변수로 관리한다
  2. 정답 출력을 위한 ans 변수는 초기값으로 0을 선언한다.
    백트래킹 결과 아무런 변화를 주지 못했을 때, 0을 출력하기 위함이다

구현 코드 설계

  1. 바로 백트래킹을 돌려준다. s의 길이가 t의 길이보다 클때 종료,
    둘이 같을 때 ans를 1로 초기화하고 종료한다.
  2. 만약 t의 끝 문자가 A라면 뒤의 값을 지우고 넘긴다.
    이때 StringBuilder를 사용하여 불변 문자열을 손쉽게 다룰 수 있도록 바꿔준다
  3. 첫 문자가 B인 경우 동일하게 StringBuilder를 사용하여 첫 문자를 지우고 뒤집는다
  4. 각 조건 후에는 StringBuilder의 값을 t 인수로 넘겨준다

출력값 설계

  1. 완성한 ans를 출력하면 정답이 된다.

과거 해결 실패 분석

시간초과 분석

  1. 정방향으로 갔을 때, 시간 초과가 발생함을 간과했기 떄문에 틀렸다
  2. 정방향에서는 최대 2^49정도의 연산이 발생할 수 있음을 계산했다면,
    정방향 백트래킹을 선택하지 않았을 것이다

역방향 구현 실패

  1. 정방향으로 했을 때는 무조건 두가지 선택지에 대한 경우를 모두 고려해야한다
  2. 하지만 역방향은 이미 만들어진 문자열을 분석해서 뺼지를 결정하므로
    조건을 넣고 구분할 수 있다.
  3. 이 점을 파악하지 못해서 구현에 실패한 것이 두번째 실패 이유이다
  4. 또한 이 방식이 시간초과가 과연 발생하지 않을 까?에 대한 불신도 한몫했다

해결방안

  1. 내가 선택한 방법에 대한 시간초과를 꼭 먼저 고려하자.
    그리고 틀렸다면, 다른 방법에 대해서 먼저 고민을 하자
  2. 역방향 구현 실패는, 두가지를 키워야한다.
    먼저 문제를 잘 이해하고, 이것을 잘 풀어내는 역량
    두번째는 구현 역량이다.

이 방법을 위해서는 꾸준히 장문의 구현 문제를 풀면서 키우는 방법밖에 없다
현재 코드트리에서 삼성 구현 문제를 풀고 있는데, 이 방법을 통해 역량을 키워나갈 것이다

정답 코드

import java.io.*;
import java.util.*;


public class Main {

    static int ans = 0;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        String s = br.readLine();
        String t = br.readLine();

        backtracking(s, t);

        bw.write(ans+"");

        br.close();
        bw.close();
    }

    private static void backtracking(String s, String t) {
        if(s.length() > t.length()){
            return;
        }

        if(s.equals(t)){
            ans = 1;
            return;
        }

        if(t.charAt(t.length()-1) == 'A'){
            StringBuilder sb = new StringBuilder(t);
            sb.deleteCharAt(t.length()-1);
            backtracking(s, sb.toString());
        }

        if(t.charAt(0) == 'B'){
            StringBuilder sb = new StringBuilder(t);
            sb.deleteCharAt(0);
            sb.reverse();
            backtracking(s, sb.toString());
        }

    }
}

문제 링크

12919번 - A와 B 2

profile
Software Developer

0개의 댓글