한 플레이어의 이득이 다른 플레이어의 손실과 정확히 일치하는 게임. Minimax 원칙으로 최적 전략 계산.
알고리즘
# 돌 게임 (N개 돌, 1 or 3개 가져감)win[0] = falsefor i = 1..N: win[i] = false if i >= 1 and not win[i-1]: win[i] = true if i >= 3 and not win[i-3]: win[i] = true# Nim XORxor = 0for p in piles: xor ^= pif xor != 0: First wins else Second wins
구현
// 돌 게임 (N, take 1 or 3) + Nim XOR#include <bits/stdc++.h>using namespace std;int main() { // 1. 돌 게임 DP (N <= 1000) int N; cin >> N; vector<bool> win(N + 1, false); for (int i = 1; i <= N; i++) { if (i >= 1 && !win[i-1]) win[i] = true; if (i >= 3 && !win[i-3]) win[i] = true; } cout << "Stone game winner: " << (win[N] ? "SK" : "CY") << "\n"; // 2. Nim XOR int k; cin >> k; long long xsum = 0; for (int i = 0; i < k; i++) { long long p; cin >> p; xsum ^= p; } cout << "Nim winner: " << (xsum ? "koosaga" : "cubelover") << "\n"; return 0;}
# 돌 게임 DP + Nim XORimport sysinput = sys.stdin.readlineN = int(input())win = [False] * (N + 1)for i in range(1, N + 1): if (i >= 1 and not win[i-1]) or (i >= 3 and not win[i-3]): win[i] = Trueprint("SK" if win[N] else "CY")k = int(input())piles = list(map(int, input().split()))xsum = 0for p in piles: xsum ^= pprint("koosaga" if xsum else "cubelover")
import java.util.*;import java.io.*;public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int N = Integer.parseInt(br.readLine()); boolean[] win = new boolean[N + 1]; for (int i = 1; i <= N; i++) { if ((i >= 1 && !win[i-1]) || (i >= 3 && !win[i-3])) win[i] = true; } System.out.println(win[N] ? "SK" : "CY"); int k = Integer.parseInt(br.readLine()); StringTokenizer st = new StringTokenizer(br.readLine()); long xsum = 0; for (int i = 0; i < k; i++) xsum ^= Long.parseLong(st.nextToken()); System.out.println(xsum != 0 ? "koosaga" : "cubelover"); }}
stdin
523 7
결과
Stone game winner: SKNim winner: cubelover
stdin
100041 2 3 4
결과
Stone game winner: CYNim winner: koosaga
복잡도
항목
값
돌 게임 DP 시간
O(N)
Nim XOR 시간
O(K) (K: 더미 수)
공간
O(N) 또는 O(1)
변형 / 활용
게임 패밀리
종류
설명
대표 문제
Take-away
일정 개수 가져감
돌 게임
Nim
여러 더미, XOR 결정
님 게임
Misere Nim
마지막 돌 가져가는 사람이 짐
nim XOR 후 예외 처리
Green Hackenbush
트리 절단 게임
하켄부시
Dawson’s Kayles
볼링핀 제거
SG 이론 활용
응용
최적 전략 게임 (Minimax): 제로섬 게임에서 최적 행동.
게임 트리 + DP: 상태 공간이 작으면 완전 탐색 DP 로 족보 판정.
함정
1. XOR 이해 오류
XOR sum 이 0 이면 선공 패, != 0 이면 선공 승. misere 에서는 예외 (모든 더미가 1 이하일 때 반대).
2. 상태 정의 누락
DP 정의 시 “현재 턴인 플레이어 기준” 임을 명확히. 실제 판정과 반대로 정의하는 실수.
💬 댓글