1 ≤ S의 길이 ≤ 999, 2 ≤ T의 길이 ≤ 1000, S의 길이 < T의 길이
이기 때문에 최대 2^999번의 연산
을 하게 되고, 시간초과는 당연한 결과 였다.package week12.boj_12904;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
//12904. A와 B
public class Somyeong {
static String s,t;
static int answer;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
s=br.readLine();
t=br.readLine();
dfs(s);
System.out.println(answer);
}
//
public static void dfs(String s) {
// System.out.println("s: "+s);
if(s.length()==t.length()) {
if(s.equals(t)) answer=1;
return;
}
dfs(s+"A");
StringBuffer sb = new StringBuffer(s);
String reverseS=sb.reverse().toString();
dfs(reverseS+"B");
}
}
어떻게하면 수행시간을 줄이기 위해 완전탐색이 아닌 방법을 할 수 있을까를 고민하였다.
그래서 S에서 T로 가는 방식이 아니라 T에서 S로 가는 방식을 생각해 봤다. 이때는 연산도 반대로 해야하기 때문에 각각의 연산을 수행할 수 있는 조건이 정해져 있어서 수행시간을 줄일 수 있을 것 같았다.
먼저 연산을 거꾸로 하는 과정을 보자
1. 문자열의 뒤에 A를 추가한다 -> (반대버전) 문자열 맨뒤 A를 제거한다.
2. 문자열을 뒤집고 뒤에 B를 추가한다 -> (반대버전) 문자열 맨뒤의 B를 제거하고 뒤집는다.
각각의 (반대방향) 연산을 하기 위해서는 다음과 같은 조건이 필요하이 있을때만 가능하다.
if(t.charAt(t.length()-1)=='A') // 문자열 t의 맨뒤가 A이면 제거
dfs(t.substring(0,t.length()-1));
if(t.charAt(t.length()-1)=='B') { // 문자열 t의 맨뒤가 B이면 제거하고 뒤집기
String newT=t.substring(0,t.length()-1);
StringBuffer sb = new StringBuffer(newT); // String에는 바로 뒤집는 함수가 없어서 StirngBuffer의 함수를 이용하여 뒤집은 뒤 String으로 반환
String reverseNewT=sb.reverse().toString();
dfs(reverseNewT);
}
package week12.boj_12904;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
//12904. A와 B
/*
*
* 1. 문자열의 뒤에 A를 추가한다 -> (반대버전) 문자열 맨뒤 A를 제거한다.
* 2. 문자열을 뒤집고 뒤에 B를 추가한다 -> (반대버전) 문자열 맨뒤의 B를 제거하고 뒤집는다.
*
*
*
*/
public class Somyeong {
static String s,t;
static int answer;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
s=br.readLine();
t=br.readLine();
dfs(t);
System.out.println(answer);
}
//t에서 s로 가는 방식 (DFS)
public static void dfs(String t) {
// System.out.println("t: "+t);
if(s.length()==t.length()) { // 문자열 t의 길이가 문자열 s의 길이와 같아지면 같은문자인지 확인하고 리턴
if(s.equals(t)) answer=1;
return;
}
if(t.charAt(t.length()-1)=='A') // 문자열 t의 맨뒤가 A이면 제거
dfs(t.substring(0,t.length()-1));
if(t.charAt(t.length()-1)=='B') { // 문자열 t의 맨뒤가 B이면 제거하고 뒤집기
String newT=t.substring(0,t.length()-1);
StringBuffer sb = new StringBuffer(newT); // String에는 바로 뒤집는 함수가 없어서 StirngBuffer의 함수를 이용하여 뒤집은 뒤 String으로 반환
String reverseNewT=sb.reverse().toString();
dfs(reverseNewT);
}
}
}