상대방 차례 함수에서 하나 이상의 패배를 받으면 이길 가능성의 수가 존재한다는 의미이므로 승리
그렇지 않다면(모두 상대방이 이긴다면) 패배
를 생각하면 된다. 이를 통해 문제를 풀어보면...
풀이 코드(첫 번째 버전)
import sys
sys.setrecursionlimit(100000)
N = int(input())
visited = [[-1]*2 for _ in range(N+1)]
def play(left, mode):
if visited[left][mode] > -1 :
return visited[left][mode] > 0
win_cnt = 0
if left >= 1 and not play(left-1, 1-mode) :
win_cnt += 1
if left >= 3 and not play(left-3, 1-mode) :
win_cnt += 1
visited[left][mode] = win_cnt
return win_cnt > 0
def solve():
result = play(N, 0)
print('SK' if result else 'CY')
solve()
이게 어렵게 생각한 버전이다. 이렇게만 풀리는 문제라면 난이도 티어가 실버 2 ~ 골드급은 되었어야 할 것 같다.
좀 더 쉬운 버전으로 풀어보자.
N이 짝수인 경우 : 무조건 창영이의 승리이다. 창영이의 전략은 다음과 같다.
둘이 어떤 수를 두던, 창영이가 돌을 가져가는 시점에서 둘이 가져간 돌의 총 누적합은 짝수가 된다. 다시 상근이의 턴이 돌아올 때 남는 돌은 무조건 짝수이다. (둘이 최선의 수를 두므로 창영이는 자신의 턴에 0이 남도록 돌을 가져가지 않는다.)
이렇게 되면 마지막 창영이의 턴에 돌이 1개 또는 3개가 남게 된다. 남는 돌을 가져가면 승리.
N이 홀수인 경우 : 무조건 상근이의 승리이다. 상근이의 전략은 다음과 같다.
상근이가 돌을 1개 먼저 가져간다고 가정하면, 남는 돌의 개수는 짝수, 상근이 대신 창영이가 먼저 시작하는 경우와같아진다.