/*
* Problem :: 9658 / 돌 게임 4
*
* Kind :: Dynamic Programming
*
* Insight
* - 답을 공식을 구해서 해결하려 했는데... 어렵다
* 좀 무식하게 풀 수 없을까?
* + 돌이 1개 남으면 상근이가 무조건 진다
* 한 번에 1,3,4 개를 가져갈 수 있으니까
* 그럼 돌이 2,4,5개 남으면 상근이가 무조건 이기네?
* # 무조건 지는 돌의 개수가 N 개면
* 돌이 N+1, N+3, N+4 개 남으면 상근이가 무조건 이긴다
* -> 그럼 N+2 개 남으면 무조건 진다는 건가...?
*
* - 일단 dp[N] 을 다 진다고 해놓고
* dp[i] == LOSE 일 때
* dp[i+1], dp[i+2], dp[i+4] 는 WIN 으로 바꾸어 주었다
* + 이렇게 풀었더니 답은 맞았다
* 규칙이 없을까 해서 한번 N=100 으로 하고 남은 돌의 개수에 따라 누가 이기는지 알아봤다
* # 남은 돌의 개수 : 누가 이기는가
* 1 : 창영
* 2 : 상근
* 3 : 창영
* 4 : 상근
* 5 : 상근
* 6 : 상근
* 7 : 상근
*
* 8 : 창영
* 9 : 상근
* 10 : 창영
* 11 : 상근
* 12 : 상근
* 13 : 상근
* 14 : 상근
*
* 15 : 창영
* 16 : 상근
* 17 : 창영
* 18 : 상근
* 19 : 상근
* 20 : 상근
* 21 : 상근
*
* ~ : ~
* -> 7씩 반복된다...?!?
*
* - 돌을 한 번에 1,2,3 개 가져가는 경우는
* 4씩 반복된다 (창영, 상근, 상근, 상근, 창영, 상근, 상근 상근, ...)
* 확실히 무슨 규칙이 있는것 같다...!!!
* + 돌을 한 번에 1,2,3 개 가져갈 수 있고 나머지 돌을 가져가면 지는 경우
* 일단 남은 돌이 N개 이하인 모든 상태를 '확실히 지는 경우' 로 초기화 한다
* L = lose, W = win
* # dp[1] : L
* dp[2] : W (1 + 1)
* dp[3] : W (1 + 2)
* dp[4] : W (1 + 3) => 확실히 지는 경우(돌이 1개 남은 경우)를 바탕으로
* 확실히 이기는 경우(돌이 2,3,4 개 남은 경우)를 알 수 있다
* dp[5] : L => 게임에 참가하는 사람들이 모두 완벽하게 게임을 하므로,
* 가능한 상태는 '확실하게 이기는 경우' 와 '확실하게 지는 경우' 둘 뿐이다
* 남은 돌이 5개 미만인 이전의 경우에 대해서 모두 살펴보았는데도
* 현재 상태가 '확실하게 지는 경우' 라면
* 이 남은 돌을 바탕으로 이기는 시나리오가 없다는 뜻이다
* dp[6] : W => (5 + 1)
* dp[7] : W => (5 + 2)
* dp[8] : W => (5 + 3)
* -> 확실히 지는 경우인 남은 돌의 개수 1을 바탕으로 얻을 수 있는 정보는
* 남은 돌이 2,3,4 개일 때 확실히 이긴다는 것이다
* 그 다음 남은 돌의 개수 5개는
* 그 이전의 경우를 살펴보아도 이기는 시나리오가 존재하지 않았으므로
* 확실히 지는 경우임을 알 수 있다
* 그러면 이 정보를 바탕으로 6,7,8 개일 때 확실히 이긴다는 것을 알 수 있다
* 그 다음 남은 돌의 개수 9개는
* 그 이전의 경우를 살펴보아도 이기는 시나리오가 존재하지 않았으므로
* 확실히 지는 경우임을 알 수 있다
* 그러면 이 정보를 바탕으로 9,10,11 개일 때 확실히 이긴다는 것을 알 수 있다
* ... 반복
* + 돌을 한 번에 1,3,4 개 가져가는 경우는
* 7씩 반복된다 (창영, 상근, 창영, 상근, 상근, 상근 상근, ...)
* 일단 남은 돌이 N개 이하인 모든 상태를 '확실히 지는 경우' 로 초기화 한다
* L = lose, W = win
* # dp[1] : L
* dp[2] : W => (1 + 1)
* dp[3] : L
* dp[4] : W => (1 + 3), (3 + 1)
* dp[5] : W => (1 + 4)
* dp[6] : W => (3 + 3)
* dp[7] : W => (3 + 4)
* dp[8] : L
* -> 확실히 지는 경우인 남은 돌의 개수 1을 바탕으로 얻을 수 있는 정보는
* 남은 돌이 2,4,5 개일 때 확실히 이긴다는 것이다
* 중요한 점은, 여기서 남은 돌이 3개 일 때 확실히 진다는 정보도 얻을 수 있다는 것이다
* 이를 토대로 4,6,7 개일 때 확실히 이긴다는 정보 또한 알 수 있다
* 그 다음 남은 돌의 개수 8개는
* 그 이전의 경우를 살펴보아도 이기는 시나리오가 존재하지 않았으므로
* 확실히 지는 경우임을 알 수 있다
* 그러면 이 정보를 바탕으로 9,11,12 개일 때 확실히 이긴다는 것을 알 수 있다
* 중요한 점은, 여기서 남은 돌이 10개 일 때 확실히 진다는 정보도 얻을 수 있다는 것이다
* 이를 토대로 11,13,14 개일 때 확실히 이긴다는 정보 또한 알 수 있다
* 그 다음 남은 돌의 개수 15개는
* 그 이전의 경우를 살펴보아도 이기는 시나리오가 존재하지 않았으므로
* 확실히 지는 경우임을 알 수 있다
* 그러면 이 정보를 바탕으로 16,18,19 개일 때 확실히 이긴다는 것을 알 수 있다
* 중요한 점은, 여기서 남은 돌이 17개 일 때 확실히 진다는 정보도 얻을 수 있다는 것이다
* 이를 토대로 18,20,21 개일 때 확실히 이긴다는 정보 또한 알 수 있다
* ... 반복
*
* Point
* - DP 였지만 알고보니 DP 를 표방한 Math 문제?
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <cstring>
using namespace std;
#define endl '\n'
// Set up : Global Variables
#define WIN true
#define LOSE false
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N; cin >> N;
// Process
bool dp[N+1];
/* 남은 돌이 N개 이하인 모든 상태를 '확실히 지는 경우' 로 초기화 */
/* 논리상, dp[0] = WIN 으로 초기화 하는 것이 맞지만
* 결과에 아무 영향을 끼치지 않으므로 무시했음 */
memset(dp, LOSE, sizeof(dp));
dp[1] = LOSE; /* 돌이 1개 남은 경우에는 확실히 짐 */
for (int i=1; i<=N; i++) {
/* 이전의 경우에서 확실히 이길 수 있는 가능한 경우를 모두 찾았음에도 불구하고
* 여전히 LOSE 로 남아있다면, 지금 다루고 있는 남은 돌 i 개의 경우는 확실히 지는 경우임 */
if (dp[i] == LOSE) { /* 확실히 지는 경우를 토대로 */
if (i+1 <= N) { dp[i+1] = WIN; } /* 확실히 이기는 경우를 찾아줌 */
if (i+2 <= N) { dp[i+2] = WIN; }
if (i+3 <= N) { dp[i+3] = WIN; }
}
}
// Control : Output
cout << ((dp[N] == WIN) ? "SK" : "CY") << endl;
/* 규칙을 찾으면 아래처럼 풀 수도 있음 */
// switch (--N % 7) {
// case 0:
// case 2:
// cout << "CY" << endl;
// break;
// case 1:
// case 3:
// case 4:
// case 5:
// case 6:
// cout << "SK" << endl;
// break;
// }
}
// Helper Functions