| 시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
|---|---|---|---|---|---|
| 3 초 | 1024 MB | 469 | 3 | 2 | 1.081% |
《Connect Four》는 $6$행 $7$열의 수직으로 세워진 직사각형 게임판에서 진행하는 게임입니다. 두 플레이어가 번갈아가며 턴을 진행하며, 각 턴에 플레이어는 아직 채워지지 않은 칸이 있는 열을 하나 골라 자신의 말을 떨어뜨립니다. 떨어뜨린 말은 채워지지 않은 가장 아래쪽 칸에 들어갑니다. 먼저 자신의 말 네 개를 가로, 세로, 또는 대각선으로 한 줄을 이루도록 하는 플레이어가 승리합니다. 편의상 먼저 말을 놓는 플레이어의 말을 빨간색, 상대편의 말을 노란색이라 하겠습니다. 또한 열 번호는 가장 왼쪽에 있는 열에서 시작하여 오른쪽으로 가면서 $1$번부터 $7$번까지 붙입니다.
여러분은 현존하는 최강의 Connect Four 인공지능을 상대로 승리해야 합니다. 여러분이 먼저 플레이합니다.
최선의 수는 다음과 같이 (게임 상태에 대해 재귀적으로) 정의합니다.
이 문제에서는 게임판을 길이가 $14$인 문자열로 인코딩합니다. 먼저 각 열을 다음과 같이 인코딩합니다.
0d, $x=127$이면 7f)간단하게 설명하자면, 열을 위에서부터 순서대로 읽고, 노란색 말을 $1$, 빨간색 말을 $0$으로 치환한 다음, 맨 왼쪽에 $1$을 추가한 이진수를 $16$진수로 쓰면 됩니다.
다음으로 게임판의 $1$열부터 $7$열까지를 인코딩한 문자열을 순서대로 이어 붙여 하나의 문자열을 만듭니다. 이 문자열이 게임판의 상태를 인코딩한 결과입니다. 아래는 인코딩한 결과가 각각 01010102010101, 0305146a032501, 55656a6a2c5555인 게임판을 나타낸 그림입니다.
플레이어의 플레이는 말을 떨어뜨릴 열의 번호로 나타낼 수 있습니다. 예를 들어 $4$, $5$, $3$, $2$, $4$, $4$, $1$, $7$ 순서로 플레이한 뒤의 게임판은 다음과 같으며, 이 게임판을 인코딩한 문자열은 0203020c030103입니다.
여러분은 아래 함수들을 구현해야 합니다.
void init()
next_move() 함수가 호출되기 전에 호출됩니다.
int next_move(std::string state)
state: 위에서 설명한 방법대로 현재 판의 상태가 인코딩된 문자열이 문제에는 $10$개의 테스트 케이스가 있습니다. 각 테스트 케이스마다 여러분은 항상 최선의 수 중 하나를 두는 인공지능과 대결합니다. 채점기는 다음과 같이 동작합니다.
"01010101010101"을 next_move() 함수의 state 인자로 넘겨줍니다.next_move() 함수의 반환값을 확인합니다. 만약 반환값이 state에 대한 최선의 수가 아니거나 $0$이라면 게임을 더 이상 진행하지 않습니다. 그렇지 않다면 반환값과 state를 바탕으로 새로운 게임판을 만듭니다.next_move() 함수의 state 인자로 넘겨줍니다.하나의 테스트 케이스에서 채점기는 항상 정해진 대로 동작합니다. 다시 말해서, 3번 과정에서 만약 최선의 수가 여러 개일 때 인공지능이 선택하는 최선의 수는, 해당 테스트 케이스의 채점 과정에서 도달할 수 있는 모든 게임판에 대해 정해져 있습니다. 인공지능의 선택은 각 테스트 케이스마다 다를 수 있습니다.
각 테스트 케이스마다, 만약 당신이 게임을 이겼다면 $2790$점을 받습���다. 그렇지 않고 만약 당신의 next_move() 함수가 $0$ 이상 $7$ 이하의 정수가 아닌 값을 반환했다면 $0$점을 받습니다. 그렇지 않다면 당신의 next_move() 함수가 최선의 수를 반환한 횟수를 $n$이라 할 때, 이 테스트 케이스에 대한 여러분의 점수는 다음 표와 같습니다.
| 조건 | 점수 |
| $n = 0$ | $0$ |
| $1 \le n \le 9$ | $2^{n-1}$ |
| $n = 10$ | $343$ |
| $n = 11$ | $486$ |
| $n = 12$ | $512$ |
| $n = 13$ | $666$ |
| $n = 14$ | $1024$ |
| $n = 15$ | $1248$ |
| $n = 16$ | $1557$ |
| $n = 17$ | $1717$ |
| $n = 18$ | $2023$ |
| $n = 19$ | $2320$ |
| $n = 20$ | $2780$ |
모든 테스트 케이스에서 채점 프로그램이 시간 내에 정상적으로 종료했을 경우에 한해, 각 테스트 케이스의 점수의 합이 여러분의 점수가 됩니다. 예를 들어, 모든 테스트 케이스에서 $n = 3$인 경우 $40$점을 받습니다.
Sample grader는 인터랙티브하게 동작합니다. Sample grader의 동작을 위해서는 당신의 next_move() 함수의 반환값이 최선의 수인지 판단하고, 인공지능이 선택할 최선의 수를 직접 입력해야 합니다.
next_move() 함수의 반환값대로 게임을 진행했을 때 게임이 끝났다면 $0$을 입력해야 합니다.next_move() 함수의 반환값이 최선의 수가 아니라면 $-1$을 입력해야 합니다.다음은 Sample grader의 동작 예시입니다.
next_move() 함수 |
input | 이전 state |
새로운 state |
|
| call | return | |||
next_move("01010101010101") |
4 | "01010101010101" |
"01010102010101" |
|
| 4 | "01010102010101" |
"01010106010101" |
||
next_move("01010106010101") |
3 | "01010106010101" |
"01010206010101" |
|
| -1 | 최선의 수가 아니라고 판단, 게임 종료 | |||
next_move() 함수가 최선의 수를 반환한 횟수: $1$, 점수: $1$ |
||||
Sample grader는 실제 채점에서 사용하는 그레이더와 다를 수 있습니다. 또한, 위 예시의 input은 실제 인공지능의 최선의 수가 아닐 수 있습니다.
Contest > BOJ User Contest > 구데기컵 > 27900번
C++17, C++20