스크류바가 코딩하는 블로그
카테고리아카이브태그소개
자동

© 2026 스쿠루. All rights reserved.

개인정보 처리방침RSS

Independent Nim

2026.08.20|1 min read|PS

AtCoder Regular Contest 225 B

AtCoder게임 이론그리디 알고리즘

문제

  • 난이도: 1112

  • 링크: Independent Nim

풀이

먼저 게임의 이기는 상태와 지는 상태를 정의하겠습니다. 어떤 게임의 상태가 주어졌을 때, 현재 턴에 최선을 다했을 때 이길 수 있다면 이기는 상태, 아니면 지는 상태라고 합시다. 예를 들어 상태 1 1 0 1은 지는 상태입니다.

AiA_iAi​중 연속된 111을 하나의 게임으로 생각하고, 전체 게임을 여러 개의 게임을 병렬로 진행하는 것으로 생각합시다. 한 번의 조작에서 인접하지 않은 여러 원소를 고를 수 있으므로, 여러 게임을 동시에 조작할 수 있습니다.

예를 들어 예제의 세 번째 테스트케이스는 N=3N = 3N=3, N=4N = 4N=4, N=5N = 5N=5인 게임을 병렬로 진행하는 것으로 생각할 수 있습니다.

만약 병렬로 진행되는 게임 중 이기는 상태인 게임이 하나라도 있다면, 각 이기는 게임을 지는 상태로 만드는 조작을 동시에 수행할 수 있습니다. 그러면 후공의 턴에 모든 게임이 지는 상태가 됩니다.

이때 후공은 어떤 행동을 하더라도 하나 이상의 게임이 이기는 상태로 변하므로 선공이 다시 모두 지는 상태로 바꿀 수 있습니다.

따라서 이 문제는 병렬로 진행되는 게임 중 이기는 상태인 것이 하나라도 있는지 판별하는 문제로 바꿔서 해결할 수 있고, 모든 AiA_iAi​가 111인 경우만 해결하면 문제를 풀 수 있습니다.

N=1N = 1N=1인 경우 이기는 상태, 222인 경우 지는 상태입니다. N≥3N \ge 3N≥3에 대해서는 다음 방법으로 이길 수 있습니다.

  1. 333으로 나눈 나머지가 111인 경우
    첫 번째부터 시작해서 1,4,7,10,…1, 4, 7, 10, \dots1,4,7,10,…번째 원소를 000으로 만듭니다.
  2. 333으로 나눈 나머지가 222인 경우
    세 번째부터 시작해서 3,6,9,12,…3, 6, 9, 12, \dots3,6,9,12,…번째 원소를 000으로 만듭니다.
  3. 333으로 나눈 나머지가 000인 경우
    위 두 가지 방법 중 아무거나 사용합니다.

이렇게 하면 전체 게임이 N=2N = 2N=2인 게임들로만 나눠지므로 후공의 턴이 되었을 때 모든 게임이 지는 상태가 됩니다.

따라서 N=2N = 2N=2를 제외하고 모두 이기는 상태입니다.

111이 연속되는 부분의 길이를 세어서 222가 아닌 것이 하나라도 존재하는지 체크하면 각 테스트케이스를 O(N)O(N)O(N)에 해결할 수 있습니다.

코드

#include <bits/stdc++.h>
using namespace std;
 
void solve() {
    int N;
    cin >> N;
 
    bool winExists = false;
    int sz = 0;
    for (int i = 1; i <= N; i++) {
        int A;
        cin >> A;
 
        if (A == 0) {
            if (sz > 0 and sz != 2) winExists = true;
            sz = 0;
        } else sz++;
    }
    if (sz > 0 and sz != 2) winExists = true;
 
    cout << (winExists ? "Alice" : "Bob") << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
 
    int t;
    cin >> t;
 
    while (t--) solve();
 
    return 0;
}

목차

  • 문제
  • 풀이
  • 코드

댓글

이름과 이메일을 입력해 댓글을 남겨주세요.