/*
* Problem :: 2661 / 좋은수열
*
* Kind :: DFS + Backtracking
*
* Insight
* - 길이가 N 미만인 나쁜 수열은 어떤 수들을 추가하더라도 길이가 N 인 나쁜 수열이 된다
* 길이가 N 인 좋은 수열은 길이 N 미만의 좋은 수열로 이루어져있다
* + 길이가 A 인 좋은 수열이 있다면 수를 추가해주면서
* 길이가 A+1, A+2, ..., N 인 좋은 수열을 찾아주자
*
* - 그런데 문제는 길이가 N 인 좋은 수열 중 가장 작은 수를 나타내는 수열을 찾아야 한다
* 추가해주는 수의 순서를 1, 2, 3 으로 하여 가장 작은 수부터 찾아낼 수 있게끔 하자
* + 하지만 현재 길이가 A 인 가장 작은 수의 좋은 수열로부터
* 길이가 N 인 좋은 수열을 만들 수 있지 않을 수도 있다!
* # 1213121, 2123212 모두 길이가 7 인 좋은 수열이다
* 길이가 8 인 좋은 수열을 만들때, 1213121 은 뒤에 어떤 수가 오더라도 나쁜 수열이 돼버린다
* 즉, N 미만 모든 길이의 좋은 수열을 찾아야 한다
* -> 실제로 현재 좋은 수열에서 수를 추가할 때
* 추가되는 수는 수열의 마지막 수와 달라야 하기 때문에
* 모두 탐색한다면 O(2^80) 이다
* => 그러나 나쁜 수열은 어떤 수들을 추가해도 나쁜 수열이므로
* Backtracking 을 적용해서 최적화를 해주자!
*
* Point
* - 사실 1 <= N <= 80 의 범위에서
* 길이 N 인 좋은 수열이 무조건 하나 이상 존재하나? 싶었는데
* 실제로 구해보니 존재하더라
* + 왜지...?
* 그러나 알아보기엔 너무많은 정수론적 지식이 들어갈 것 같아
* 증명은 스킵한다
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
using namespace std;
#define endl '\n'
// Set up : Global Variables
int N;
string A;
// Set up : Functions Declaration
bool isGood(const string& s);
bool f(string s);
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
cin >> N;
// Process
bool isPossible = f("");
// Control : Output
cout << ((isPossible) ? A : "-1") << endl;
}
// Helper Functions
bool isGood(const string& s)
/* 문자열 s 를 수열로 보고
* 수열의 마지막 수가 포함된 임의의 길이의 인접한 두 개의 부분 수열을 검사하여
* 좋은 수열이면 true 를 반환, 그 외 false 를 반환 */
{
int len = s.length();
for (int i=1; i<=len/2; i++) {
string a1 = s.substr(len-2*i, i);
string a2 = s.substr(len-i, i);
if (a1 == a2) return false;
} return true;
}
bool f(string s)
/* 문자열 s 를 수열로 보고
* 길이가 N 인 가장 작은 수의 좋은 수열을 찾으면 true 를 반환, 그 외 false 를 반환 */
{
if (s.length() == N) { /* 길이가 N 인 가장 작은 수의 좋은 수열을 찾았다면 */
A = s; /* 길이 N 인 좋은 수열을 전역변수 A 에 저장 */
return true;
}
else {
for (char c : {'1', '2', '3'}) {
/* c 라는 수를 추가한 새로운 수열이 좋은 수열이며
* 이 수열을 통해 길이가 N 인 가장 작은 수의 좋은 수열을 만들 수 있다면
* 현재 함수의 실행을 종료시키고 true 를 반환 */
if (isGood(s+c) && f(s+c)) {
return true;
}
}
}
/* s 로는 길이가 N 인 가장 작은 좋은 수열을 만들 수 없음 */
return false;
}