※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 17080번 문제인 결함 게임이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/17080 

 

17080번: 결함 게임

첫째 줄에 돌의 개수 N이 주어진다. (1 ≤ N ≤ 5,000,000)

www.acmicpc.net

게임이론 문제이다.

 

적은 개수의 돌의 경우를 먼저 살펴보면 다음과 같다:

돌이 1개 있다면 탑이 하나밖에 만들어질 수 없으므로 선공의 승리이다.

돌이 2개 있다면 선공이 2인 돌을 먼저 골라 탑을 1개로 유도할 수 있으므로 선공의 승리이다.

돌이 3개 있다면 선공이 무엇을 골라도 후공이 탑을 2개로 유도할 수 있다.

(선공이 1을 고른다면 후공이 3을 골라 탑 2개로 유도할 수 있고, 선공이 2 또는 3을 고른다면 후공이 1을 골라 탑 2개로 유도할 수 있다.)

돌이 4개 있다면 선공이 2를 고른 후 후공이 (강제로) 1을 고르면 선공이 3을 고르는 것으로 탑 3개를 만들어 승리할 수 있다.

 

이를 일반화해보자.

1) 돌이 짝수개이면 선공의 승리이다. 전략은 다음과 같다:

돌이 두개 남기 전까지 선공은 두번째로 작은 돌만을 계속 골라 새로운 돌탑의 바닥으로 한다. 후공은 남은 가장 작은 돌을 그 위에 올리는 행동밖에 할 수 없다.

마지막 남은 돌 2개로 탑 1개 또는 2개를 만드는 것을 강요하여 선공이 승리를 차지한다.

 

2) 돌이 4n+1개 꼴이면 선공의 승리이다. 전략은 다음과 같다:

돌 1개 남을 때까지 두번째로 작은 돌만을 계속 골라 새로운 바닥의 돌탑으로 하면 짝수개의 돌탑이 만들어진다. 남은 하나의 돌을 새로 배치하여 홀수개의 돌탑을 만든다.

 

3) 돌이 4n+3개 꼴이면 후공의 승리이다. 전략은 다음과 같다:

Case 1) 선공이 첫 번째 돌을 집어간 경우:

남아있는 돌은 짝수개이다. 돌이 2개 남을 때까지 두번째로 작은 돌만을 계속 골라 새로운 바닥의 돌탑으로 하자. 이 때, 만들어진 돌탑의 개수에 따라 남은 돌중 작은 돌을 선택할지 큰 돌을 선택할지 결정한다.

Case 2) 선공이 첫 번째 돌이 아닌 돌을 집어간 경우:

후공은 첫번째 돌을 가져간다. 다음 선공의 행동을 기다린다.

Case 2-0) 돌이 하나 남은 경우:

선공은 남은 돌을 배치한다. 이것으로 짝수개의 돌탑이 완성되었으므로 후공의 승리이다.

Case 2-1) 선공이 첫 번째 돌을 집어간 경우:

"Case 1"의 과정을 반복한다.

Case 2-2) 선공이 첫 번째 돌이 아닌 돌을 집어간 경우:

후공은 첫번째 돌을 가져간다. 이제, 처음으로 돌아간다.

 

따라서, 위의 내용을 구현하는 것으로 문제를 해결할 수 있다.

 

아래는 제출한 소스코드이다.

#include <iostream>
using namespace std;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int N; cin >> N;
	if (N % 4 == 3) cout << 2;
	else cout << 1;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 17394 // C++] 핑거 스냅  (0) 2021.08.27
[BOJ 11238 // C++] Fibo  (0) 2021.08.26
[BOJ 2655 // C++] 가장높은탑쌓기  (0) 2021.08.24
[BOJ 1932 // C++] 정수 삼각형  (0) 2021.08.23
[BOJ 2631 // C++] 줄세우기  (0) 2021.08.22

+ Recent posts