알고리즘/백준

백준 2661 - 좋은수열(Java)

D_Helloper 2024. 5. 12. 15:13

https://www.acmicpc.net/problem/2661

문제

숫자 1, 2, 3으로만 이루어지는 수열이 있다. 임의의 길이의 인접한 두 개의 부분 수열이 동일한 것이 있으면, 그 수열을 나쁜 수열이라고 부른다. 그렇지 않은 수열은 좋은 수열이다.

다음은 나쁜 수열의 예이다.

  • 33
  • 32121323
  • 123123213

다음은 좋은 수열의 예이다.

  • 2
  • 32
  • 32123
  • 1232123

길이가 N인 좋은 수열들을 N자리의 정수로 보아 그중 가장 작은 수를 나타내는 수열을 구하는 프로그램을 작성하라. 예를 들면, 1213121과 2123212는 모두 좋은 수열이지만 그 중에서 작은 수를 나타내는 수열은 1213121이다.

입력

입력은 숫자 N하나로 이루어진다. N은 1 이상 80 이하이다.

출력

첫 번째 줄에 1, 2, 3으로만 이루어져 있는 길이가 N인 좋은 수열들 중에서 가장 작은 수를 나타내는 수열만 출력한다. 수열을 이루는 1, 2, 3들 사이에는 빈칸을 두지 않는다.

예제 입력 1 복사

7

예제 출력 1 복사

1213121

 

풀이

일단 빈 문자열을 선언 후,

백트래킹을 돌면서 1부터 3까지 추가해본다.

그렇게 만들어진 문자열을 check() 메서드에 던져서 가능한지 불가능한지를 확인한다.

문자열의 길이로 나누고 앞부분, 뒷부분을 비교해서 같은지를 보는 것.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BJ_2661_좋은수열 {
    static int N;
    static boolean exit = false;
    static String answer = "";
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        back(0);

    }
    public static void back(int cnt)
    {
        if(exit) return;
        if(cnt==N){
            System.out.println(answer);
            exit = true;
            return;
        }
        for(int i=1; i<4; i++)
        {
            answer+=i;
                if(check(answer))
                {
                    back(cnt+1);
                }
            answer = answer.substring(0,answer.length()-1);
        }

    }

    public static boolean check(String str) {
        for(int i = 1; i <= str.length() / 2; i++) {
            String front = str.substring(str.length() -i * 2, str.length() - i);
            String back = str.substring(str.length() - i, str.length());
            if(front.equals(back)) return false;
        }
        return true;
    }
}