From eae754adc7464763737597431a6b7ac757ddc939 Mon Sep 17 00:00:00 2001 From: nypc Date: Mon, 31 Aug 2026 13:55:58 +0900 Subject: [PATCH] Add NYPC 2026 Final Problems. --- src/routes/2026/final_m.mdx | 376 ++++++++++++++++++++++++++++++++ src/routes/2026/final_r.mdx | 297 +++++++++++++++++++++++++ src/routes/2026/index.tsx | 10 + src/routes/2026/pre_m.mdx | 22 -- src/routes/en/2026/final_m.mdx | 387 +++++++++++++++++++++++++++++++++ src/routes/en/2026/index.tsx | 5 + src/routes/en/2026/pre_m.mdx | 22 -- 7 files changed, 1075 insertions(+), 44 deletions(-) create mode 100644 src/routes/2026/final_m.mdx create mode 100644 src/routes/2026/final_r.mdx create mode 100644 src/routes/en/2026/final_m.mdx diff --git a/src/routes/2026/final_m.mdx b/src/routes/2026/final_m.mdx new file mode 100644 index 000000000..ff5f9bd42 --- /dev/null +++ b/src/routes/2026/final_m.mdx @@ -0,0 +1,376 @@ +--- +title: NEXT VISION +stage: 마스터 트랙 파이널 라운드 +--- + +
+ +
+ +
+ +**NEXT VISION**은 건물을 건설하고 전사들을 훈련시켜 적의 본부를 파괴하는 2인 턴제 전략 게임입니다. + +## 게임 규칙 + +### 1 | 개요 + +게임은 **전장** 위에서 진행됩니다. 전장은 $0$번부터 $N-1$번까지 번호가 붙은 $N$개의 **구역**으로 나뉘어 있으며, 중심을 기준으로 점대칭을 이룹니다. 가장 왼쪽($0$번)과 오른쪽($N-1$번) 구역에는 각 플레이어의 **본부**가 있습니다. 본부가 없는 구역 중 $K$개는 **기지**를 건설 가능한 **거점**입니다. + +전장의 크기 $N$은 $180 < N < 250$, 거점의 수 $K$는 $\left\lceil \sqrt N-1 \right\rceil \le K \le \left\lfloor \sqrt N+4 \right\rfloor$ 입니다. $N$과 $K$는 반드시 홀수입니다. + +각 플레이어는 본부에 위치한 **전사** $3$명과 **금화** $750$개로 시작합니다. 본부는 초기에 레벨 $1$, 체력 $10$이며, 전사의 초기 체력은 $4$입니다. 본부가 파괴된 플레이어는 패배합니다. + +플레이어는 매일 다음 명령을 원하는 만큼 내릴 수 있습니다. + +- **건설**: 이미 있는 아군 건물(본부 및 기지)을 업그레이드하거나, 건물이 없는 거점 위에 새로운 기지를 건설할 수 있습니다. + - 건설 명령을 수행할 위치에는 아군 전사가 한 명 이상 있고, 적 전사가 없어야 합니다. +- **이동**: 현재 이동 상태가 아닌 전사 하나에게 특정 구역으로 이동하라고 명령합니다. +- **훈련**: 본부에서 전사를 $n$명 훈련합니다. $n$은 `본부의 훈련 가능 전사 수` 이하인 $0$ 이상의 정수여야 합니다. + - 훈련 명령은 하루에 한 번 초과로 할 수 없습니다. + +플레이어가 명령을 전달하고 나면, 하루가 시작됩니다. 하루는 **아침**, **낮**, **저녁**으로 나뉩니다. + +#### 아침 + +**건설 단계** → **이동 단계** → **훈련 단계** 순서대로 진행됩니다. + +- **건설 단계**에서는, 금화를 지불하고 새로 기지를 건설하거나 기존에 지어진 건물을 업그레이드합니다. +- **이동 단계**에서는, 오늘 이동 명령을 받았거나 이동 중이었던 전사들이 **이동 규칙**(섹션 3)에 따라 최대 한 칸 이동합니다. + - 이동 명령을 새로 받은 병사마다 금화 $10$개를 지불합니다. 단, 목적지가 아군 건물이라면 지불하지 않습니다. +- **훈련 단계**에서는, 훈련시키기로 한 전사 수만큼 본부에서 전사를 훈련하고 한 명당 금화 $120$개를 지불합니다. + - 훈련된 전사의 체력은 본부의 레벨에 따릅니다. + - 전사는 훈련되면 고유한 번호를 받으며, 먼저 훈련된 전사가 더 작은 번호를 가집니다. + +#### 낮 + +**전투 단계**가 진행됩니다. + +- **전투 단계**에서는, **전투 규칙**(섹션 3)에 따라 적 전사와 건물을 공격합니다. + +#### 저녁 + +**노동 단계** → **보급 단계** 순서대로 진행됩니다. + +- **노동 단계**에서는 각 건물에서 $15 \times x$만큼 금화를 얻습니다. $x$는 `해당 구역의 아군 전사 수`와 `해당 건물의 노동 가능 전사 수` 중 작은 값입니다. +- **보급 단계**에서는, 번호 오름차순으로 각 전사가 $2$만큼의 금화를 식비로 소모합니다. 만약 식비가 부족한 경우, 해당 전사는 체력을 1 잃습니다. 이때 전사의 체력이 $0$이 된 경우 전사는 퇴각하여 전장에서 벗어납니다. + +--- + +### 2 | 건물 + +건물은 수입을 책임지는 원천입니다. + +건물은 업그레이드 또는 수리 시 체력이 최대 체력까지 가득 찹니다. + +건물에는 포탑이 있어, 매일 전투 단계 시작 시에 공격력만큼 같은 구역에 공격을 수행합니다. 상세 설명은 전투 단계를 확인해 주세요. + +각 구역에 대해 건설 명령은 하루에 최대 한 번만 내릴 수 있습니다. 즉, 한 건물을 하루에 두 번 이상 업그레이드 하거나, 오늘 새로 지어진 건물을 오늘 업그레이드할 수 없습니다. + +#### 본부 + +각 플레이어는 처음에 레벨 $1$인 본부를 가지고 시작합니다. 본부는 각 플레이어마다 하나씩만 가질 수 있습니다. + +| 레벨 | 업그레이드 비용 | 전사 최대 체력 | 본부 최대 체력 | 포탑 공격력 | 훈련 가능 전사 수 | 노동 가능 전사 수 | +| :---------: | :-------------: | :------------: | :------------: | :---------: | :---------------: | :---------------: | +| $1$ | - | $4$ | $10$ | $1$ | $1$ | $1$ | +| $2$ | 금화 $600$개 | $5$ | $15$ | $2$ | $1$ | $2$ | +| $3$ | 금화 $1\,000$개 | $6$ | $20$ | $2$ | $2$ | $3$ | +| $4$ | 금화 $2\,000$개 | $7$ | $25$ | $3$ | $2$ | $4$ | +| $5$ | 금화 $3\,000$개 | $8$ | $30$ | $3$ | $3$ | $5$ | +| $5+$ (수리) | 금화 $1\,000$개 | - | - | - | - | - | + +#### 기지 + +각 플레이어는 원하는 만큼 기지를 지을 수 있습니다. 기지에서는 본부와 달리, 전사를 훈련시킬 수 없습니다. + +| 레벨 | 건설 또는 업그레이드 비용 | 최대 체력 | 포탑 공격력 | 노동 가능 전사 수 | +| :---------: | :-----------------------: | :-------: | :---------: | :---------------: | +| $1$ | 금화 $500$개 | $6$ | $1$ | $1$ | +| $2$ | 금화 $550$개 | $12$ | $1$ | $2$ | +| $3$ | 금화 $600$개 | $18$ | $2$ | $3$ | +| $3+$ (수리) | 금화 $500$개 | - | - | - | + +--- + +### 3 | 이동과 전투 + +#### 이동 규칙 + +이동 명령을 수행 중인 각 전사는 현재 구역에 적이 없다면, 현재 위치에서 목적지까지 인접한 두 구역 사이의 직선 거리 합이 가장 짧은 경로를 따라 한 구역 이동합니다. 엄밀하게는 다음과 같습니다. + +
+ +중심이 $(x_1, y_1)$와 $(x_2, y_2)$인 두 구역 간의 **직선 거리**를 $\left \lceil \sqrt{(x_1 - x_2) ^2 + (y_1 - y_2)^2 } \right \rceil$, 즉 두 구역의 중심 사이의 유클리드 거리의 올림이라 합시다. 이때 각 전사는 현재 위치에서 목적지까지 인접한 구역을 통해서만 이동하되, 경로 위에서 연속한 두 구역 사이의 **직선 거리** 합이 최소가 되는 경로를 찾아 해당 경로에서 현재 위치 바로 다음에 있는 구역으로 이동합니다. 그러한 경로가 여럿이라면, 구역 번호가 더 작은 구역으로 이동합니다. + +
+ +이동 명령을 한 번 내리면 해당 전사는 목적지에 도착할 때까지 다른 이동 명령을 받을 수 없습니다. 전사에게 내려진 이동 명령은 목적지에 도착하는 즉시 끝납니다. + +- 금화를 소모하는 이동 명령을 내린 후, 목적지에 기지가 건설되더라도 소모한 금화가 반환되지는 않습니다. +- 금화를 소모하지 않는 이동 명령을 내린 후, 목적지의 건물이 파괴되더라도 이동이 중단되지는 않습니다. + +#### 전투 규칙 + +1. 건물이 있는 구역에서, 해당 건물은 포탑 공격 횟수만큼 공격을 수행합니다. +2. 각 구역에서, 나와 상대 전사 수가 각각 $a$, $b$라 할 때, 상대는 $a$번, 나는 $b$번 공격당합니다. 체력이 $0$인 전사는 전투가 끝날 때까지 퇴각하지 않으므로, 포탑 공격으로 체력이 $0$이 된 전사도 $a$와 $b$에 포함됩니다. +3. 전투가 종료되고, 체력 $0$인 전사들이 퇴각하여 전장에서 벗어납니다. 또한 체력 $0$인 건물이 파괴됩니다. + +매 공격은 다음 규칙을 따라 수행됩니다. + +- 그 구역에서 체력이 $0$이 아닌 상대편의 전사 중, 체력이 가장 작은 전사의 체력이 $1$ 감소합니다. 만약 그러한 전사가 여럿이라면, 번호가 가장 앞선 전사가 대상이 됩니다. +- 만약 그 구역에 체력이 $0$이 아닌 상대편의 전사가 없고, 체력이 $0$이 아닌 상대편의 건물이 있다면 해당 건물의 체력이 $1$ 감소합니다. + +--- + +### 4 | 시야 + +플레이어는 자신의 모든 전사와 건물의 시야를 합쳐서 볼 수 있는 범위만 관찰할 수 있습니다. + +본부, 기지, 전사는 모두 자신이 있는 구역과 최대 $2$만큼 떨어져 있는 구역까지 볼 수 있습니다. + +인접한 구역 간의 거리는 $1$이며, 두 구역의 거리는 인접한 구역을 통해서 이동할 수 있는 경로 중 가장 짧은 것의 길이로 계산됩니다. + +--- + +### 5 | 게임 종료 + +게임이 시작하고 $400$일 동안 어느 한 플레이어의 본부가 파괴되었다면 파괴되지 않은 플레이어의 승리입니다. + +두 본부가 동시에 파괴된 경우 혹은 게임이 시작하고 $400$일 동안 양쪽 본부가 파괴되지 않은 경우, 본부의 체력이 더 많은 쪽이 승리합니다. + +만약 본부의 체력도 같다면 무승부가 됩니다. + +--- + +### 6 | 세부 규칙: 전장 생성 방식 + +전장의 구조는 입력으로 주어지기 때문에, 생성 규칙을 알아야만 문제를 해결할 수 있는 것은 아닙니다. + +전장이 어떠한 방식으로 생성되는지 알고 싶으신 분은 아래를 읽을 것을 권장드립니다. + +
+ +### 전장 + +전장은 무한한 크기의 유클리드 평면 위에 있습니다. + +- 전장에는 정확히 $N = 2N'+1$개의 다각형 모양 구역이 있습니다. +- 각 구역은 다각형의 테두리를 제외한 내부에 있는 점인 **중심**을 하나씩 가집니다. +- 두 구역이 인접하다는 것은, 두 구역이 적어도 하나의 변을 공유한다는 것입니다. + +- 가장 왼쪽($0$번 구역)과 오른쪽의 구역($N-1$번 구역)에는 각 플레이어의 **본부**가 세워져 있습니다. + +전장에는 특수한 구역인 거점이 있습니다. + +- $K = 2K'+1$개의 구역은 거점입니다. 거점에는 건물을 건설할 수 있습니다. + +전장은 매 게임마다 구조가 무작위로 생성됩니다. 구체적인 규칙은 아래에서 확인할 수 있습니다. + +#### 생성 과정 + +아래 설명에서 $L = 10^4$, $D = 800$, $A = 24$입니다. +매 시행은 독립이며, 특정한 범위에서 대상을 뽑을 때, 해당 범위 안에 있는 대상이 모두 같은 확률로 선택됩니다. + +(1) $N'$과 $K'$을 정합니다. + +- $N'$은 $90$ 이상 $124$ 이하의 정수 중에서 무작위로 정해집니다. +- 이후에 $K'$은 $N = 2N'+1$이라고 할 때 $K = 2K'+1$이 $\left\lceil \sqrt N-1 \right\rceil \le K \le \left\lfloor \sqrt N+4 \right\rfloor$를 만족하는 정수 중에서 무작위로 정해집니다. + +(2) 유클리드 좌표평면에서, 원점을 중심으로 삼고 반지름이 $L$인 원을 $S$라고 합시다. + +(3) 처음에 $P = \{(0, 0)\}$입니다. 다음을 $N'$회 반복합니다. + +- $S$의 경계 또는 내부에 있는 격자점을 하나 뽑아 $u=(x_u, y_u)$라 합니다. +- 만약 어떤 점 $(x_v, y_v) = v \in P$가 존재해서 다음 중 하나를 만족한다면 $u$를 다시 뽑습니다. $\mathrm{dist}(u, v)$는 점 $u$와 $v$ 사이의 유클리드 거리입니다. + - $x_u = x_v$ + - $\mathrm{dist}(u, v) < D$ +- $P$에 $u$와 $u$를 원점 $O$ 기준으로 점대칭한 점인 $u'$를 추가합니다. + +반복 후 $|P| = 2N' + 1$입니다. $x$좌표가 증가하는 순서대로 $0$번부터 $N-1$번까지 번호를 붙입니다. + +(4) 원점 $O$를 중심으로 하고 반지름이 $1.5L$인 원 $C$를 그린 후 $A$등분합니다. 구체적으로, $C$와 $x$축이 교차하는 두 점을 각각 $t_1$과 $t_2$라고 할 때, $t_1$과 $t_2$를 잇는 위쪽 호와 아랫쪽 호를 각각 $A/2$등분하는 점들을 찾습니다. 이 점들을 $Q$라고 합니다. + +(5) $P \cup Q$에 있는 점들을 기준으로 보로노이 다이어그램과 델루네 삼각분할을 계산합니다. $P$의 각 점과 듀얼 관계인 보로노이 다이어그램의 다각형들의 각 무게중심을 모아 $P'$이라고 하고, 각 점에 부여된 번호를 그대로 다시 붙입니다. 이후 $P' \cup Q$를 기준으로 보로노이 다이어그램과 델루네 삼각분할을 다시 계산합니다. + +(6) $t$번 점과 듀얼 관계가 있는 보로노이 다이어그램의 다각형이 $t$번 구역이 되고 $t$번 점은 $t$번 구역의 중심이 됩니다. 각 구역은 그 구역의 중심이 점 $u$라고 할 때 $u$와 델루네 삼각분할에서 이어져 있으면서 $v \in P$인 점 $v$가 중심인 구역과 이어져 있습니다. 쉽게 말해, 각 구역은 델루네 삼각분할로 이어진 구역 중 $Q$로부터 만들어지지 않은 구역들과 인접합니다. + +(7) 처음에 $R = \{N'\}$입니다. 다음을 $K'$회 반복합니다. + +- $t \in [1, N-2]$이고 $t \not \in R$인 무작위 $t$를 고릅니다. $0$번과 $N-1$번 구역에는 본부가 있으므로 거점이 될 수 없습니다. +- 만약 하나 이상의 $r \in R$에 대해 $t$번 구역 또는 $N-1-t$번 구역이 $r$번 구역과 인접해 있다면, $t$를 다시 뽑습니다. +- 만약 $t$번 구역과 $N-1-t$번 구역이 인접해 있다면, $t$를 다시 뽑습니다. +- $R$에 $t$와 $N-1-t$를 추가합니다. + +반복 후 $|R| = 2K' + 1$입니다. 각 $r \in R$에 대해, $r$번 구역은 거점입니다. + +
+ +--- + +## 인터랙션 + +참가자의 프로그램은 표준 입력(`stdin`)에서 입력을 받아 각 명령에 따라 동작해야 합니다. + +#### 준비 + +``` +READY (LEFT | RIGHT) +N K +x_{0} ... x_{N-1} +y_{0} ... y_{N-1} +p_{0} ... p_{K-1} +a_{0} b_{0,0} ... b_{0,a_{0}-1} +... +a_{N-1} b_{N-1,0} b_{N-1,1} ... b_{N-1,a_{N-1}-1} +``` + +플레이어의 진영과 맵에 대한 정보를 알려주는 명령입니다. + +- 첫 번째 줄에 어느 쪽 본부를 사용하는지가 주어집니다. +- 두 번째 줄에 $N$과 $K$가 주어집니다. +- $x_i$와 $y_i$는 각각 $i$번 구역 중심의 $x$좌표와 $y$좌표입니다. +- $p_i$는 거점의 구역 번호입니다. +- $i$번 구역은 $a_i$개의 구역과 인접해 있습니다. $i$번 구역과 인접한 구역의 목록은 $b_{i,j}$ ($0 \le j < a_i$)로 주어집니다. + +플레이어는 입력 준비 완료를 의미하는 `OK`를 $1\,000$ms 안에 출력해야 합니다. 그렇지 않은 경우 시간 초과(TLE)로 패배합니다. + +#### 명령 시작 + +``` +START TURN T +``` + +매 턴의 시작마다, `START` 명령어가 주어집니다. $T$는 오늘이 몇 번째 날인지를 나타냅니다. + +#### 명령 제출 + +``` +COMMAND +... +MOVE a d +TRAIN n +UPGRADE d +... +END +``` + +플레이어는 `COMMAND` 명령어로 명령 단계를 시작할 수 있습니다. 플레이어는 원하는 개수만큼의 명령어를 순서 상관 없이 제출할 수 있습니다. 그 후 `END` 명령어로 목록의 끝을 표시합니다. + +처음 주어지는 전사들의 번호는 왼쪽 플레이어의 경우 `A1`, `A2`, `A3`이고, 오른쪽 플레이어의 경우 `B1`, `B2`, `B3`입니다. + +- `MOVE`: 번호가 $a$인 전사를 $d$번 구역으로 이동시키는 이동 명령을 내립니다. +- `TRAIN`: 본부에서 $n$명의 전사를 훈련합니다. 이 명령은 명령 단계에 반드시 $1$개 이하로 존재해야 합니다. +- `UPGRADE`: $d$번 구역에 있는 아군 건물을 업그레이드하거나 수리합니다. $d$번 구역에 건물이 없다면, 대신 기지를 건설합니다. + +플레이어는 `START` 명령어를 받고 난 후부터 $100$ms 안에 목록을 제출해야 합니다(`END` 명령어를 출력해야 합니다). 만약 $100$ms를 초과하여 사용하였다면, 초과한 시간 $t$ms에 대해 $\displaystyle \left \lceil \frac{t}{100} \right \rceil$개의 초읽기를 소모합니다. 남은 초읽기가 없는 상태에서 시간을 초과했다면, 시간 초과(TLE)로 패배합니다. 각 플레이어는 처음에 $5$개씩의 초읽기를 가지고 시작합니다. + +유효하지 않은 명령을 제출했다면, 그 즉시 규칙 위반(WA)로 패배합니다. 동시에 유효하지 않은 명령을 제출했다면, 무승부가 됩니다. + +#### 결과 보기 + +``` +TURN T +TIME T_x R_x T_y R_y +UPGRADE N +t_1 d_1 +... +TRAIN N +a_1 ... a_N +MOVE N +a_1 d_1 +... +DAMAGE N +C_1 a_1 h_1 +... +SIEGE N +t_1 d_1 h_1 +... +WARRIOR W +a_1 r_1 h_1 +... +BUILDING B +t_1 r_1 k_1 l_1 h_1 +... +``` + +두 플레이어가 모두 명령 제출을 정상적으로 마쳤다면, 결과가 반환됩니다. `UPGRADE`, `TRAIN`, `MOVE`, `DAMAGE`, `SIEGE` 섹션에서 $N = 0$인 경우, 해당 섹션에는 뒤따르는 줄이 주어지지 않습니다. + +- `TURN` $T$: 현재 $T$일차에 대한 정보가 표기됨을 알려줍니다. +- `TIME` $T_x$ $R_x$ $T_y$ $R_y$: + - $T_x$와 $T_y$는 각각 이번 턴에 자신과 상대 플레이어가 시간을 얼마나 사용했는지를 나타냅니다(ms). + - $R_x$와 $R_y$는 자신과 상대 플레이어에게 몇 개의 초읽기가 남아있는지를 나타냅니다. +- `UPGRADE` $N$: + - 이번 턴에 건설, 업그레이드 또는 수리된 **아군** 건물의 수 $N$이 주어집니다. + - 이어 $N$개의 줄에 건물의 소속 $t_i$($t_i$는 `A`나 `B`), 해당 건물이 있는 구역 번호 $d_i$가 차례대로 주어집니다. +- `TRAIN` $N$: + - 이번 턴에 훈련된 **아군** 전사의 수 $N$이 주어집니다. + - 이어 다음 줄에 새롭게 훈련된 전사의 번호가 차례대로 주어집니다. 전사의 번호는 유일하게 부여되며, 각 플레이어별로 1부터 차례대로 증가합니다. + - 전사의 번호는 항상 `A` 또는 `B`에 정수를 하나 이어 붙인 형태입니다(e.g. `A12`, `B7`). `A`로 시작하면 왼쪽 플레이어의 전사이고, `B`로 시작하면 오른쪽 플레이어의 전사입니다. +- `MOVE` $N$: + - 이번 턴에 이동한 **아군** 전사의 수 $N$이 주어집니다. + - 이어 $N$개의 줄에 이동한 전사의 번호 $a_i$와 이동한 구역 번호 $d_i$가 차례대로 주어집니다. +- `DAMAGE` $N$: + - 이번 턴에 **아군** 전사에 발생한 피해 정보의 개수 $N$이 주어집니다. + - 이어 $N$개의 줄에 피해 원인 $C_i$, 피해를 입은 전사의 번호 $a_i$, 입힌 피해량 $h_i$가 차례대로 주어집니다. + - $C_i$는 다음 중 하나입니다: `TURRET`(건물 포탑에 의한 피해), `COMBAT`(전사 간 전투에 의한 피해), `HUNGER`(보급 단계 식비 부족에 의한 피해). +- `SIEGE` $N$: + - 이번 턴에 **아군** 건물에 발생한 피해 정보의 개수 $N$이 주어집니다. + - 이어 $N$개의 줄에 건물의 소속 $t_i$(`A` 또는 `B`), 피해를 입은 건물이 있는 구역 번호 $d_i$와 입힌 공성 피해량 $h_i$가 차례대로 주어집니다. +- `WARRIOR` $W$: + - 현재 시야 안에 있는 **모든** 전사의 수 $W$가 주어집니다. + - 이어 $W$개의 줄에 전사의 번호 $a_i$, 위치한 구역 번호 $r_i$, 현재 체력 $h_i$가 차례대로 주어집니다. +- `BUILDING` $B$: + - 현재 시야 안에 있는 **모든** 건물의 수 $B$가 주어집니다. + - 이어 $B$개의 줄에 건물의 소속 $t_i$(`A` 또는 `B`), 위치한 구역 번호 $r_i$, 종류 $k_i$(`HQ` 또는 `BASE`), 레벨 $l_i$, 현재 체력 $h_i$가 차례대로 주어집니다. + +각 턴의 결과는 `END` 명령어로 마무리됩니다. + +### 게임 종료 + +``` +FINISH +``` + +어떤 이유로든 게임이 종료되면, `FINISH` 명령어가 주어집니다. **이 명령을 받으면 게임 진행 상황에 관계 없이 프로그램은 즉시 정상적으로 종료되어야 합니다.** 다시 말해 턴이 종료되고 나서 결과 대신 `FINISH` 명령어가 주어진다면, 프로그램은 결과를 읽으려 시도하기 전에 즉시 종료해야 합니다. + +## 게임 시뮬레이터 + +[시뮬레이터 바로가기](https://d1thb30t7rs13h.cloudfront.net/) + +위 시뮬레이터에 로그를 붙여 넣어 게임 플레이를 분석할 수 있습니다. + +## CLI 툴 + +[CLI 툴 다운로드](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/nation-fr-providing.zip) + +위 CLI 툴을 활용하여 로컬에서 AI를 대결시켜볼 수 있습니다. + +## 예제 코드 + +대회에서 지원하는 각 언어로 작성된 예제 코드를 아래에서 확인할 수 있습니다. + +- C: [sample-code.c](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.c) +- C++: [sample-code.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.cpp) +- Python: [sample-code.py](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.py) +- Rust: [sample-code.rs](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.rs) +- Java: [Main.java](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/Main.java) +- JavaScript: [sample-code.js](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.js) +- TypeScript: [sample-code.ts](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.ts) +- C#: [sample-code.cs](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.cs) +- Kotlin: [sample-code.kt](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.kt) +- Go: [sample-code.go](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.go) +- Scala: [sample-code.scala](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.scala) +- Lua: [sample-code.lua](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.lua) + +## 샘플 AI + +| 배틀 번호 | 설명 | 샘플 AI | +| :-------: | :----------------------------------- | :--------------------------------------------------------------------------------------------------------------------------- | +| $1$ | 기초적인 공격형 전략을 구사합니다. | [1_rush.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/1_rush.cpp) | +| $2$ | 기초적인 기습형 전략을 구사합니다. | [2_ambush.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/2_ambush.cpp) | +| $3$ | 기초적인 밸런스형 전략을 구사합니다. | [3_deathball.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/3_deathball.cpp) | +| $4$ | 기초적인 경계형 전략을 구사합니다. | [4_blockade.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/4_blockade.cpp) | +| $5$ | 기초적인 방어형 전략을 구사합니다. | [5_eco.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/5_eco.cpp) | + +> 샘플 AI 코드는 실제 대회 진행 시에는 제공되지 않았습니다. diff --git a/src/routes/2026/final_r.mdx b/src/routes/2026/final_r.mdx new file mode 100644 index 000000000..a54b4ab75 --- /dev/null +++ b/src/routes/2026/final_r.mdx @@ -0,0 +1,297 @@ +--- +title: 슈퍼루키 +stage: 루키 트랙 파이널 라운드 +--- + +
+ +
+ +
+ +$N \times M$ 크기의 격자 속에서 프레임을 읽어들이며 캐릭터를 최대 $10\,000$번 조작하여, 맵에 있는 코인들을 최대한 수집하세요. + +## 가이드 + +맵은 아래 사진과 같이 여섯 종류가 있으며, 각 종류마다 $\textrm{small}$, $\textrm{medium}$, $\textrm{large}$로 크기가 나뉩니다. + +사진은 각 종류의 $\textrm{small}$ 크기 예시 맵으로, 맵 전체 사진 및 파일이 제공됩니다: [예시 맵 다운로드](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-maps.zip) + +> 전체 샘플 맵은 실제 대회 진행 시에는 제공되지 않았습니다. ([다운로드](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/samples-full.zip)) + +| **Handcrafted** | **Choice** | +| :----------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------: | +| ![Handcrafted small](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/preview-image/handcrafted_small.png) | ![Choice small](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/preview-image/choice_small.png) | + +| **Jump** | **Pits** | +| :--------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------: | +| ![Jump small](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/preview-image/jump_small.png) | ![Pits small](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/preview-image/pits_small.png) | + +| **Puzzle** | **Maze** | +| :------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------: | +| ![Puzzle small](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/preview-image/puzzle_small.png) | ![Maze small](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/preview-image/maze_small.png) | + +예시로 제공되는 것 외의 맵 파일이나 사진은 주어지지 않으며, 맵 생성기 또한 제공되지 않습니다. **대신**, 제출할 때마다 각 종류의 $\textrm{small}$, $\textrm{medium}$ 맵에서 해당 코드의 플레이 로그를 받아 볼 수 있습니다. 제출 시 보여지는 맵은 모든 제출 간에 고정이며, 바뀌지 않습니다. + +중간평가에서는 $\textrm{large}$ 맵에 대한 대표 답안의 플레이 로그도 제공됩니다. 중간평가에서는 시드를 다르게 하여 매번 새로운 맵을 생성하며, 시드로 인해 맵의 랜덤 요소가 바뀔 수 있습니다. + +모든 맵들은 $\textrm{small}$에서 $\textrm{medium}$, $\textrm{large}$로 갈 수록 크기가 단계적으로 커지며, `Handcrafted` 유형을 제외한 모든 맵들은 유형별로 절차적 맵 생성에 의해 자동으로 생성됩니다. `Handcrafted` 유형은 맵이 고정되어 있으며, $\textrm{medium}$ 및 $\textrm{large}$로 크기가 커질 때마다 아래로 단계가 하나씩 추가됩니다. + +플레이어는 제출 및 중간평가에서 제공되는 로그를 통해 맵을 더 자세히 파악하거나 제출한 코드를 어떻게 개선할지 살펴볼 수 있습니다. + +## 맵 + +맵은 $N$개의 행과 $M$개의 열, 총 $N \times M$개의 칸으로 이루어져 있습니다. + +또한 각 칸은 $6$개의 행과 $6$개의 열, 총 $6 \times 6$개의 픽셀로 이루어져 있습니다. + +맵에서 가장 왼쪽 위의 칸은 $(0, 0)$입니다. 칸의 좌표 $(i, j)$는 (행, 열)이며, 픽셀 좌표 $(y, x)$와 같은 순서입니다. 칸 $(i, j)$는 픽셀 좌표 $(6i \ldots 6i{+}5,\; 6j \ldots 6j{+}5)$ 영역에 대응됩니다. + +맵의 각 칸에는 **캐릭터**, **벽**, **상자**, **점프 블록**, **코인**, **가시**, **보호막 아이템**이 있거나, 아무것도 없는 빈 칸일 수 있습니다. + +플레이어는 매 프레임마다 캐릭터를 중심으로 $48$개의 열과 $48$개의 행, 총 $2304$개의 주변 픽셀을 볼 수 있습니다. + +## 조작 + +플레이어는 매 프레임마다 명령을 출력할 수 있습니다. 한 프레임에 여러 명령을 함께 낼 수 있으며, 형식은 출력 (명령)을 따릅니다. 조건을 만족하지 않는 명령은 무시됩니다. 무시된 명령은 그 명령으로 인한 가속이나 점프를 일으키지 않으며, 같은 프레임의 다른 동작(감속, 중력, 이미 가진 속도로 인한 이동 등)은 그대로 처리됩니다. + +- 이동 방향이 벽이나 밀 수 없는 상자로 막혀 있지 않다면, 왼쪽 또는 오른쪽으로 **좌우 이동**을 할 수 있습니다. +- 캐릭터의 하단이 벽/상자와 접해 있거나, 점프 블록에 겹친 상태를 점프 타임이라 합니다. 점프 타임은 매 프레임 상하 이동이 시작되기 전에 한 번 판정됩니다. 이번 프레임이 점프 타임이거나, 직전 프레임이 점프 타임이었는데 그 프레임에 점프 또는 점프 유지를 하지 않았다면, **점프**를 할 수 있습니다. +- 새 점프가 불가능한 상태라면, 직전 프레임에 점프 또는 점프 유지가 이뤄진 경우에 한해 추가로 최대 $2$프레임 간 **점프를 유지**할 수 있습니다. 점프 명령이 한 프레임이라도 끊기면 남은 유지 횟수도 사라집니다. +- 아무 조건 없이 **특수 점프**를 할 수 있습니다. 단, 특수 점프를 한 프레임 수만큼 추후 비용 계산에 반영되므로 주의하여 사용해야 합니다. 특수 점프는 점프가 아니므로, 특수 점프를 한 직후의 프레임에는 점프를 유지할 수 없습니다. + +캐릭터가 이동하는 과정에서 가시와 픽셀이 겹치는 순간, 보호막 개수가 양수라면 $1$ 소모되고, $0$개라면 추후 비용 계산에 반영됩니다. 또한 맵에서 해당 가시 오브젝트는 영구적으로 사라집니다. + +캐릭터가 이동하는 과정에서 코인이나 보호막 아이템과 픽셀이 겹치는 순간, 해당 아이템의 개수가 $1$ 증가합니다. 또한 맵에서 그 오브젝트는 영구적으로 사라집니다. + +점프 블록은 아이템이 아니며, 캐릭터와 겹쳐도 사라지지 않습니다. + +코인 개수, 보호막 개수는 처음에 $0$으로 시작합니다. + +## 동작 + +아래에서 번호의 나열로 서술된 동작들은 번호 순서대로 처리되며, 서로 다른 두 번호의 동작이 동시에 처리되지 않음에 주의하세요. + +아래에서 "부딪힌다"는 표현은 캐릭터의 이동이 멈추지 않을 시 해당 오브젝트와 겹칠 수 있는 상태를 의미합니다. + +### 상하 이동 (점프/낙하) + +이 문단에서 다루는 속도는 상하 속도입니다. 상하 이동에서 다루는 속도는 좌우 이동에서 다루는 속도와 독립적입니다. 또한, 상하 이동은 좌우 이동보다 먼저 이뤄집니다. + +1. 이번 프레임에 점프가 이뤄졌다면, (점프/점프 유지/특수 점프에 관계 없이) 캐릭터의 속도가 $-3$으로 설정됩니다. +2. 속도가 음수라면 위로 1픽셀씩, 속도의 절대값만큼 이동을 시도합니다. 벽/상자에 부딪힐 시 이동이 멈추고, 속도가 $0$으로 초기화됩니다. +3. 속도가 양수라면 아래로 1픽셀씩, 속도의 값만큼 이동을 시도합니다. 벽/상자에 부딪힐 시 이동이 멈추고, 속도가 $0$으로 초기화됩니다. +4. 하단이 벽/상자와 접해 있지 않고, 이번 프레임에 점프가 이뤄지지 않았을 경우, 속도가 $1$ 증가합니다. 단, 속도는 $6$을 넘지 않습니다. 조건을 만족하지 못해 무시된 점프 명령은 점프가 이뤄진 것으로 보지 않습니다. + +이때, **상자 또한 낙하할 수 있습니다.** 상자는 아래로 1픽셀씩 속도만큼 이동을 시도하며, 벽/상자/캐릭터에 부딪힐 시 이동이 멈추고 속도가 $0$으로 초기화됩니다. 하단이 벽/상자/캐릭터와 접해 있지 않으면 속도가 $1$ 증가하며, 속도는 $6$을 넘지 않습니다. 공중에 뜬 직후 첫 프레임의 속도는 $0$이므로, 그 프레임에는 상자가 낙하하지 않습니다. + +낙하는 아래쪽에 있는 개체부터 수행되며, 같은 높이에서는 캐릭터가 상자보다 먼저 처리됩니다. 따라서 여럿이 포개진 상자들이 같은 프레임에 함께 낙하할 수 있습니다. + +### 좌우 이동 + +이 문단에서 다루는 속도는 좌우 속도입니다. 좌우 이동에서 다루는 속도는 상하 이동에서 다루는 속도와 독립적입니다. 또한, 좌우 이동은 상하 이동보다 나중에 이뤄집니다. + +1. 캐릭터의 속도가 $0$이 아닌 상황에서, 좌우 이동 명령을 내리지 않았거나, 속도와 반대 방향으로 이동 명령을 내렸다면, 속도의 절대값이 $1$ 줄어듭니다. +2. 플레이어가 이번 프레임에 좌우 이동 명령을 내렸다면, + - 해당 방향으로 벽이 접해 있거나, 밀 수 없는 상자가 접해 있다면, 속도는 변하지 않으며 밀기도 일어나지 않습니다. + - 해당 방향으로 접해 있는 상자가 없다면, 왼쪽 이동의 경우 속도가 $1$ 감소하고, 오른쪽 이동의 경우 속도가 $1$ 증가합니다. 단, 속도의 절대값은 $4$를 넘지 않습니다. + - 해당 방향으로 밀리는 상자가 접해 있다면, 속도는 변하지 않은 채 그 상자를 같은 방향으로 1픽셀 민 뒤에 캐릭터가 1픽셀 이동합니다. 밀리는 상자들이 연속하여 붙어 있을 수 있으며, 이 경우 모든 상자가 한꺼번에 밀립니다. +3. 속도가 음수라면 왼쪽으로 1픽셀씩, 속도의 절대값만큼 이동을 시도합니다. 벽/상자에 부딪힐 시 이동이 멈추고 속도가 $0$으로 초기화됩니다. +4. 속도가 양수라면 오른쪽으로 1픽셀씩, 속도의 값만큼 이동을 시도합니다. 벽/상자에 부딪힐 시 이동이 멈추고 속도가 $0$으로 초기화됩니다. + +#### 상자 + +벽에 의해 해당 방향으로의 이동이 막히는 상자는 밀 수 없습니다. 또한, 다른 밀리지 않는 상자에 의해 막히는 상자 또한 밀 수 없습니다. 상자는 가시나 아이템에 의해 막히지 않으며, 겹칠 수 있습니다. + +캐릭터와 접해 있는 밀리는 상자가 둘 이상일 시, 해당하는 모든 상자를 밉니다. 반대로, 하나라도 밀리지 않는 상자일 시, 이동/밀기는 중단됩니다. + +하단이 벽/상자와 접해 있는 밀리는 상자를 밀 시, 해당 상자의 상단과 접해 있는 밀리는 상자들까지 한꺼번에 밀립니다. 이 작동은 한꺼번에 밀리는 상자들 모두에 연쇄적으로 적용됩니다. 캐릭터는 이 받침으로 보지 않습니다. 위에 얹힌 상자의 이동이 벽에 막히면 그 상자만 남고, 나머지 밀기는 그대로 이뤄집니다. + +상자는 한 프레임에 1픽셀 넘게 밀리지 않습니다. + +명령을 내린 시점에 상자가 접해 있지 않았을 시, 캐릭터가 상자에 부딪혀도 상자는 밀리지 않습니다. + +## 입력 + +첫 번째 줄에 맵의 세로 크기 $N$, 가로 크기 $M$, 서브태스크 유형 $S$가 공백으로 구분되어 차례대로 주어집니다. ($10 \le N \le 500$, $10 \le M \le 500$, $N \times M \le 10\,000$, $S$는 `Handcrafted`, `Choice`, `Jump`, `Pits`, `Puzzle`, `Maze` 중 하나) + +이후 프레임의 정보가 두 줄씩 주어집니다. 조작 전의 시작 프레임이 먼저 주어지고, 이후 조작할 때마다 조작이 처리된 직후의 프레임이 주어집니다. `FINISH`를 출력하면 더 이상 프레임이 주어지지 않습니다. 각 프레임의 정보는 다음 형식을 따릅니다. + +첫 번째 줄에는 현재 프레임에 보유 중인 코인 개수, 보호막 개수, 캐릭터의 좌상단 픽셀 좌표 $y$, $x$로 네 개의 수가 공백으로 구분되어 차례대로 주어집니다. ($0 \le y \le 6N - 6$, $0 \le x \le 6M - 6$) + +두 번째 줄에는 현재 프레임의 $48 \times 48$ 크기의 픽셀 출력이 **인코딩되어** 한 줄로 주어집니다. + +### 픽셀 출력 + +| 문자 | 오브젝트 | +| ---- | ------------- | +| `@` | 캐릭터 | +| `#` | 벽 | +| `O` | 상자 | +| `$` | 코인 | +| `+` | 점프 블록 | +| `*` | 보호막 아이템 | +| `^` | 가시 | +| `.` | 빈 칸 | + +한 픽셀에 여러 오브젝트가 겹칠 경우, 목록의 상단에 있는 것일 수록 더 위에 표시됩니다. + +캐릭터, 벽, 가시, 상자, 점프 블록은 칸 전체($6 \times 6$)를 차지합니다. + +코인과 보호막 아이템은 아래와 같이 가운데 영역만 차지합니다. + +``` +...... +..$$.. +.$$$$. +.$$$$. +..$$.. +...... +``` + +
+ +``` +...... +..**.. +.****. +.****. +..**.. +...... +``` + +### 인코딩 + +픽셀 출력은 개행을 모두 제거한 뒤, 같은 문자가 연속한 구간을 `(문자)(개수)` 형태로 이어서 쓴 압축입니다. 개수가 $1$이어도 생략하지 않으며, 개수는 한 자리보다 클 수 있습니다. + +예를 들어 다음과 같은 $6 \times 6$ 픽셀이 있을 때, + +``` +...... +..$$.. +.$$$$. +.$$$$. +..$$.. +...... +``` + +다음처럼 인코딩됩니다. + +``` +.8$2.3$4.2$4.3$2.8 +``` + +### 조건 + +초기에 한 칸에 두 오브젝트가 동시에 또는 겹쳐서 존재하는 경우는 주어지지 않습니다. + +출력 중앙 $(21..26, 21..26)$에는 항상 캐릭터가 위치해 있습니다. + +맵 테두리($i = 0$, $i = N{-}1$, $j = 0$, $j = M{-}1$에 해당하는 칸)는 모두 벽입니다. 맵 바깥은 빈 칸(`.`)으로 표시됩니다. + +맵에는 적어도 하나의 코인이 존재합니다. + +서브태스크에서 `Handcrafted`를 제외한 모든 맵은 각 유형에 따라 절차적으로 랜덤하게 생성됩니다. `Handcrafted`는 맵이 바뀌지 않습니다. 생성 알고리즘은 각 유형마다 모든 중간평가에서 동일하며, 시드만 바뀝니다. + +입력으로 주어지는 모든 맵은 보호막 없이 가시에 부딪히지 않으며 특수 점프를 사용하지 않고 모든 코인을 수집할 수 있음이 보장됩니다. + +## 출력 (명령) + +매 프레임마다 다음 명령 중 원하는 명령들을 골라 출력해야 합니다. 조건을 만족하지 않는 명령은 무시되며, 그 명령으로 인한 가속이나 점프는 일어나지 않습니다. 이는 **올바른 출력**이며, 해당 프레임은 정상적으로 진행됩니다. + +| 명령 | 조작 | +| ---- | --------------- | +| `<` | 왼쪽으로 이동 | +| `>` | 오른쪽으로 이동 | +| `J` | 점프/점프 유지 | +| `S` | 특수 점프 | + +각 프레임의 출력에 대해, 첫 줄에 `FINISH` 또는 선택한 명령의 개수를 $4$ 이하의 음이 아닌 정수로 출력해야 합니다. $0$을 출력하면 명령을 내지 않고 그 프레임만 진행합니다. 이후 해당 개수만큼 줄마다 명령을 출력합니다. + +**매 프레임의 출력을 마친 뒤에는 반드시 출력 버퍼를 비워야 합니다.** 출력 버퍼를 비우는 방법에 대해서는 각 언어의 예제 코드, 또는 공식 레퍼런스 페이지를 참고하세요. + +왼쪽으로 이동과 오른쪽으로 이동을 동시에 할 경우, 오른쪽으로 이동만 시도됩니다. 점프와 특수 점프를 동시에 할 경우, 특수 점프만 시도됩니다. 또한, 한 프레임에 한 종류의 명령을 여러 번 사용할 수 없습니다. + +첫 줄이 `FINISH`도 $4$ 이하의 음이 아닌 정수도 아닌 경우, 표에 없는 명령을 출력한 경우, 명령에 여분의 토큰이 붙은 경우, 한 프레임에 같은 종류의 명령을 두 번 이상 출력한 경우는 모두 **올바르지 않은 출력**이며, 채점 규칙에 따라 $0$점입니다. + +**프로그램 종료 전, 반드시 `FINISH`를 출력해야 함에 주의하세요.** `FINISH`를 출력하면 그 이후 프레임은 주어지지 않으며, 프로그램은 반드시 정상적으로 실행을 종료해야 합니다. 프로그램의 제한 시간은 2초이며, 프로그램이 2초를 전부 소모하고도 `FINISH`를 출력하지 않으면 시간 초과로 강제 종료됩니다. + +$10\,000$번째 조작을 수행한 뒤에는 `FINISH` 외의 응답을 출력할 수 없습니다. + +### 채점 + +올바르지 않은 출력을 한 경우, 즉 출력 형식을 맞추지 않은 경우 $0$점입니다. + +아닌 경우, $T$를 종료 시점까지 플레이어가 수행한 조작 개수, $t$를 조작이 수행된 횟수, $c_{\max}$를 맵의 전체 코인 개수, $c_t$를 플레이어가 $t$ 시점에 수집한 코인 개수, $s_t$를 $t$ 시점까지 특수 점프 명령을 낸 프레임 수, $h_t$를 $t$ 시점까지 보호막 없이 가시에 부딪힌 횟수라고 할 때 **비용**이 다음과 같은 방법으로 정해집니다. + +- $\textrm{Cost(t)} = \left\lfloor\left(1 - \dfrac{c_t}{c_{\max}+s_t+h_t}\right) \times 10^6\right\rfloor$ +- $\textrm{Cost} = \displaystyle\min_{t=0}^{T}{\textrm{Cost(t)}}$ +- 비용이 낮을수록 더 좋은 결과입니다. + +이때의 각 테스트케이스의 점수는 다음과 같은 방법으로 정해집니다. + +- 전체 참가자의 수: $n_\textrm{tot}$ +- 자신보다 비용이 낮은 참가자의 수: $n_\textrm{lose}$ +- 자신과 비용이 같은 다른 참가자의 수: $n_\textrm{draw}$ +- $\textrm{Score} = \left\lfloor 10^6 \left(1 - 0.5\sqrt{\dfrac{n_\textrm{lose} + 0.5 n_\textrm{draw}}{n_\textrm{tot}}}\right) \right\rfloor$ + +챌린지 문제의 최종 점수는 최종 평가에 사용된 각 테스트 케이스 점수의 평균이 됩니다. 비슷하게, 중간 평가의 점수는 중간 평가에 사용된 각 테스트 케이스 점수의 평균이 되며, 이 점수는 참고용으로 최종 점수에 반영되지 않습니다. 평가에는 예제 코드보다 낮은 비용을 받은 제출만 채점됩니다. + +문제의 점수는 각 테스트 케이스 별로 매겨지며, 최종 점수는 테스트 케이스별 점수의 평균으로 계산됩니다. + +### 중간 평가 데이터 + +각 중간 평가마다 $6$개 유형(`Handcrafted`, `Choice`, `Jump`, `Pits`, `Puzzle`, `Maze`)과 $3$개 크기($\textrm{small}$, $\textrm{medium}$, $\textrm{large}$)의 모든 조합에 대해 맵이 $1$개씩, 총 $18$개의 테스트 케이스가 사용됩니다. 이 $18$개 테스트 케이스에 대한 플레이 로그가 제공됩니다. + +### 최종 평가 데이터 + +최종 평가 역시 같은 $18$개 조합에 대해 채점하며, 모든 유형·크기에 대해 $20$개의 데이터로 채점합니다. + +## CLI 툴 + +[CLI 툴 다운로드](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/superrookie-providing.zip) + +위 CLI 툴을 활용하여 로컬에서 AI를 실행시켜볼 수 있습니다. + +## 시뮬레이터 + +[시뮬레이터](https://d3welzoa03ib.cloudfront.net/)에서는 맵 파일을 업로드하여 직접 플레이해보거나, 로그 파일을 업로드하여 재생해볼 수 있습니다. 제공된 맵 파일이나 제출 및 중간평가에서 제공되는 로그 파일만 쓸 필요는 없으며, 직접 만든 맵 파일이나, 자신의 컴퓨터에서 실행한 로그도 사용 가능합니다. + +## 예제 코드 + +대회에서 지원하는 각 언어로 작성된 예제 코드를 아래에서 확인할 수 있습니다. + +- C: [sample-code.c](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.c) +- C++: [sample-code.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.cpp) +- Python: [sample-code.py](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.py) +- Rust: [sample-code.rs](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.rs) +- Java: [sample-code.java](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.java) +- JavaScript: [sample-code.js](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.js) +- TypeScript: [sample-code.ts](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.ts) +- C#: [sample-code.cs](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.cs) +- Kotlin: [sample-code.kt](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.kt) +- Go: [sample-code.go](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.go) +- Scala: [sample-code.scala](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.scala) +- Lua: [sample-code.lua](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/superrookie-fr-8y0cp53w/sample-code/sample-code.lua) + +## 파일 형식 + +### 로그 + +플레이어는 CLI 툴 또는 채점을 통해 게임이 진행된 로그를 받을 수 있습니다. 해당 파일은 시뮬레이터에서도 재생 가능합니다. + +로그의 첫 번째 줄에는 맵의 세로 크기 $N$, 가로 크기 $M$, 서브태스크 유형 $S$, 플레이어가 수행한 조작 개수 $T$가 공백으로 구분되어 차례대로 주어집니다. + +두 번째 줄부터 플레이어가 각 프레임 사이에 출력한 명령이 출력 (명령) 형식과 동일한 형식으로 주어집니다. 실행을 끝내는 `FINISH`는 조작이 아니므로 기록되지 않습니다. + +이후 플레이어에게 전송된 프레임 $T+1$개의 정보가 차례대로 주어집니다. 각 프레임의 형식은 다음과 같습니다. + +첫 번째 줄에는 해당 프레임에 보유 중인 코인 개수, 보호막 개수, 캐릭터의 좌상단 픽셀 좌표 $y$, $x$로 네 개의 수가 공백으로 구분되어 차례대로 주어집니다. + +두 번째 줄에는 해당 프레임의 $48 \times 48$ 크기의 픽셀 출력이 **인코딩되어** 한 줄로 주어집니다. + +### 맵 + +첫 번째 줄에 맵의 세로 크기 $N$, 가로 크기 $M$, 서브태스크 유형 $S$가 공백으로 구분되어 차례대로 주어집니다. ($10 \le N \le 500$, $10 \le M \le 500$, $N \times M \le 10\,000$, $S$는 `Handcrafted`, `Choice`, `Jump`, `Pits`, `Puzzle`, `Maze` 중 하나) + +두 번째 줄부터 $N$개의 줄에 걸쳐 줄마다 픽셀 문자로 이뤄진 길이 $M$의 문자열이 주어집니다. 각 문자는 해당 위치의 셀에 있는 오브젝트를 의미합니다. 초기에 한 셀에 두 오브젝트가 동시에 또는 겹쳐서 존재하는 경우는 없습니다. diff --git a/src/routes/2026/index.tsx b/src/routes/2026/index.tsx index 2dc01150b..660251c57 100644 --- a/src/routes/2026/index.tsx +++ b/src/routes/2026/index.tsx @@ -11,6 +11,8 @@ export const problems = { ["pre_2b", "씨앗 운반 (챌린지)"], ], master: [["pre_m", "NEXT NATION"]], + rookieFinal: [["final_r", "슈퍼루키"]], + masterFinal: [["final_m", "NEXT VISION"]], } as const; const List = () => { @@ -30,6 +32,14 @@ const List = () => { 마스터 트랙 — Qualification Round + + 루키 트랙 — Final Round + + + + 마스터 트랙 — Final Round + + ); }; diff --git a/src/routes/2026/pre_m.mdx b/src/routes/2026/pre_m.mdx index 4999a02b3..0d863e207 100644 --- a/src/routes/2026/pre_m.mdx +++ b/src/routes/2026/pre_m.mdx @@ -9,8 +9,6 @@ stage: 마스터 트랙 예선 라운드 -
-

## 게임 규칙 @@ -57,12 +55,8 @@ stage: 마스터 트랙 예선 라운드 - **노동 단계**에서는 각 건물에서 $15 \times x$만큼 금화를 얻습니다. $x$는 `해당 구역의 아군 전사 수`와 `해당 건물의 노동 가능 전사 수` 중 작은 값입니다. - **보급 단계**에서는, 번호 오름차순으로 각 전사가 $2$만큼의 금화를 식비로 소모합니다. 만약 식비가 부족한 경우, 해당 전사는 체력을 1 잃습니다. 이때 전사의 체력이 $0$이 된 경우 전사는 퇴각하여 전장에서 벗어납니다. -
- --- -
- ### 2 | 건물 건물은 수입을 책임지는 원천입니다. @@ -86,8 +80,6 @@ stage: 마스터 트랙 예선 라운드 | $5$ | 금화 $3\,600$개 | $8$ | $30$ | $3$ | $3$ | $5$ | | $5+$ (수리) | 금화 $1\,000$개 | - | - | - | - | - | -
- #### 기지 각 플레이어는 원하는 만큼 기지를 지을 수 있습니다. 기지에서는 본부와 달리, 전사를 훈련시킬 수 없습니다. @@ -99,12 +91,8 @@ stage: 마스터 트랙 예선 라운드 | $3$ | 금화 $1\,000$개 | $18$ | $2$ | $3$ | | $3+$ (수리) | 금화 $500$개 | - | - | - | -
- --- -
- ### 3 | 이동과 전투 #### 이동 규칙 @@ -133,12 +121,8 @@ stage: 마스터 트랙 예선 라운드 - 그 구역에서 체력이 $0$이 아닌 상대편의 전사 중, 체력이 가장 작은 전사의 체력이 $1$ 감소합니다. 만약 그러한 전사가 여럿이라면, 번호가 가장 앞선 전사가 대상이 됩니다. - 만약 그 구역에 체력이 $0$이 아닌 상대편의 전사가 없고, 체력이 $0$이 아닌 상대편의 건물이 있다면 해당 건물의 체력이 $1$ 감소합니다. -
- --- -
- ### 4 | 게임 종료 게임이 시작하고 $200$일 동안 어느 한 플레이어의 본부가 파괴되었다면 파괴되지 않은 플레이어의 승리입니다. @@ -147,12 +131,8 @@ stage: 마스터 트랙 예선 라운드 만약 본부의 체력도 같다면 무승부가 됩니다. -
- --- -
- ### 5 | 세부 규칙: 전장 생성 방식 전장의 구조는 입력으로 주어지기 때문에, 생성 규칙을 알아야만 문제를 해결할 수 있는 것은 아닙니다. @@ -215,8 +195,6 @@ stage: 마스터 트랙 예선 라운드 -
- --- ## 인터랙션 diff --git a/src/routes/en/2026/final_m.mdx b/src/routes/en/2026/final_m.mdx new file mode 100644 index 000000000..32c414456 --- /dev/null +++ b/src/routes/en/2026/final_m.mdx @@ -0,0 +1,387 @@ +--- +title: NEXT VISION +stage: Master Track Final Round +--- + +
+ +
+ +
+ +**NEXT VISION** is a two-player turn-based strategy game where players build buildings, train warriors, and destroy the opponent's headquarter. + +## Rules + +### 1 | Introduction + +The game is played on the **battlefield**. The battlefield consists of $N$ areas indexed from $0$ through $N-1$, point-symmetric with respect to the origin. The leftmost area #$0$ and the rightmost area #$N-1$ each have a player's **headquarter**. Among areas without headquarter, $K$ areas are **stronghold**s, where **base**s can be built. + +$N$, the size of battlefield, satisfies $180 < N < 250$, and $K$, the number of strongholds, satisfies $\left\lceil \sqrt N-1 \right\rceil \le K \le \left\lfloor \sqrt N+4 \right\rfloor$. $N$ and $K$ are both odd numbers. + +Each player starts the game with $3$ **warriors** on their headquarter and $750$ gold. The headquarter is initially at level $1$, HP $10$, and the warriors are initially at HP $4$. If the headquarter is destroyed, the owner loses. + +Every day, a player can deliver the following commands as many times as they want: + +- **Upgrade**: A player can upgrade existing allied buildings (headquarter or base), or build a new base on a stronghold with no building. + - To deliver an Upgrade command, there should be one or more allied warriors and no enemy warriors at the target area. +- **Move**: A player can command a warrior that is not currently in the moving state to move to a desired area. + - However, if there is an allied building on the desired area, no gold is consumed. +- **Train**: By using $120 \times n$ gold, train $n$ warriors on the headquarter. $n$ is a non-negative integer less than or equal to `# of trainable warriors`. + - You cannot use Train command more than once on the same day. + +After delivering the commands, the day starts. The day consists of **The Morning**, **The Daytime**, and **The Evening**. + +#### The Morning + +The Morning consists of **Building Step** → **Moving Step** → **Training Step**, in order. + +- In the **Building Step**, new bases are raised and buildings already built are upgraded by spending gold. +- In the **Moving Step**, the warriors that received Move commands on the same day or were already in moving state move up to one area according to the **Movement Rule** (Section 3). + - You spend $10$ golds for every warrior that received the move command on the current day. However you do not pay if the destination have allied building. +- In the **Training Step**, train the commanded number of warriors and spend $120$ gold for each warrior. + - The HP of each warrior is determined by the level of the headquarter. + - The warriors are indexed uniquely, and warriors trained earlier have smaller indices. + +#### The Daytime + +**Battle Step** occurs. + +- In the **Battle Step**, warriors attack other warriors or buildings with respect to the **Battle Rule** (Section 3). + +#### The Evening + +The Evening consists of **Labor Step** → **Supply Step**, in order. + +- In the **Labor Step**, each building produces $15 \times x$ gold, where $x$ is the minimum value of `# of allied warriors in the area` and `# of labor slots`. +- In the **Supply Step**, each warrior consumes $2$ gold in increasing order of number. If there is not enough gold when a warrior tries to consume gold, the warrior loses 1 HP. If the HP of the warrior becomes 0, the warrior retreats, leaving the battlefield. + +--- + +### 2 | Building + +Buildings are the source of income. + +After raising, upgrading or repairing buildings, the HP becomes its maximum HP. + +At the start of each battle step, the turret in the building performs attacks in the same area as many times as its attack damage (AD). For further information, please refer to the Battle Step. + +For each area, an Upgrade command can be delivered at most once per day. A building cannot be upgraded twice on the same day, nor can a building be upgraded on the same day it is built. + +#### Headquarter (HQ) + +Each player starts with a headquarter of level $1$. Only one headquarter is allowed for each player. + +| Level | Upgrade cost | Max HP of Warrior | Max HP of HQ | AD of turret | # of trainable warrior | # of labor slot | +| :-----------: | :-----------: | :---------------: | :----------: | :----------: | :--------------------: | :-------------: | +| $1$ | - | $4$ | $10$ | $1$ | $1$ | $1$ | +| $2$ | $600$ gold | $5$ | $15$ | $2$ | $1$ | $2$ | +| $3$ | $1\,000$ gold | $6$ | $20$ | $2$ | $2$ | $3$ | +| $4$ | $2\,000$ gold | $7$ | $25$ | $3$ | $2$ | $4$ | +| $5$ | $3\,000$ gold | $8$ | $30$ | $3$ | $3$ | $5$ | +| $5+$ (Repair) | $1\,000$ gold | - | - | - | - | - | + +#### Base + +Each player can build as many bases as they want. Unlike headquarter, warriors cannot be trained on base. + +| Level | Raise/Upgrade cost | Max HP | AD of turret | # of labor slot | +| :-----------: | :----------------: | :----: | :----------: | :-------------: | +| $1$ | $500$ gold | $6$ | $1$ | $1$ | +| $2$ | $550$ gold | $12$ | $1$ | $2$ | +| $3$ | $600$ gold | $18$ | $2$ | $3$ | +| $3+$ (Repair) | $500$ gold | - | - | - | + +--- + +### 3 | Movement and Battle + +#### Movement Rule + +If there is no enemy in the same area as a warrior that is performing a Move command, it moves by one area along a path whose sum of straight line distances between adjacent areas is minimum. Technical details are as follows: + +
+ +Define **straight line distance** between $(x_1, y_1)$ and $(x_2, y_2)$ as $\left \lceil \sqrt{(x_1 - x_2) ^2 + (y_1 - y_2)^2 } \right \rceil$, i.e., the ceiling of Euclidean distance. Each warrior finds a path to its target by moving only through adjacent areas, minimizing the sum of straight line distances between consecutive areas on the path, and moves to the next area on that path. If multiple such paths exist, it moves to the area with the smaller index. + +
+ +After delivering a Move command to a warrior, it enters the moving state and cannot receive another Move command before it arrives at the target area. The moving state ends as soon as it arrives at the target area. + +- After delivering a Move command that costs gold, the gold is not refunded even if the building is built on the target area. +- After delivering a Move command that does not cost gold, the movement is not aborted even if the building is destroyed on that area. + +#### Battle Rule + +1. In each area with a building, the building performs attacks as many times as its turret AD. +2. In each area, say the numbers of my warriors and the opponent's warriors are $a$ and $b$; the opponent is attacked $a$ times and I am attacked $b$ times. Warriors with $0$ HP do not retreat until the battle finishes, so warriors whose HP became $0$ from turret attacks are still counted in $a$ and $b$. +3. After the battle finishes, warriors with $0$ HP retreat and leave the battlefield. Buildings with $0$ HP are destroyed. + +The rule of each attack is as follows: + +- Among the opponent's warriors with positive HP, decrease the HP of the warrior with minimum HP by 1. If multiple such warriors exist, the warrior with the lowest number is targeted. +- If there is no opponent's warrior with positive HP, and the opponent's building has positive HP, the HP of the opponent's building is decreased by 1. + +--- + +### 4 | Vision + +A player can only observe the range covered by the combined vision of all of their warriors and buildings. + +Headquarters, bases, and warriors can all see the area they are in and every area at most $2$ away from it. + +The distance between adjacent areas is $1$, and the distance between two areas is the length of the shortest path that travels between them through adjacent areas. + +--- + +### 5 | Game End + +During $400$ days from the game start, if the Headquarter is destroyed, then the player whose Headquarter is not destroyed wins. + +If two headquarters are destroyed on the same day, or both headquarters are not destroyed in $400$ days, then the side whose HQ has more HP wins. + +If the HP of two HQ are equal, then the game ends in a draw. + +--- + +### 6 | Detailed Rules: Battlefield Generation Method + +Since the structure of the battlefield is given as input, you do not need to know the generation rules to solve the problem. + +If you would like to know how the battlefield is generated, the details are as follows: + +
+ +### Battlefield + +The battlefield can be represented as an infinitely sized Euclidean plane. + +- The battlefield has exactly $N = 2N'+1$ polygonal areas. + +- Each area has a **center**, which is a point inside the polygon excluding the border. + +- Two areas are adjacent if they share at least one side. + +- Each player's **headquarter** is established in the leftmost area #$0$ and the rightmost area #$N-1$. + +The battlefield contains special areas called strongholds. + +- $K = 2K'+1$ areas are strongholds. Buildings can be constructed on strongholds. + +The battlefield structure is randomly generated for every game. Specific rules can be found below. + +#### Generation Process + +In the description below, $L = 10^4$, $D = 800$, and $A = 24$. + +Each trial is independent, and when selecting a target from a specific range, all targets within that range are selected with equal probability. + +(1) Determine $N'$ and $K'$. + +- $N'$ is randomly selected from integers between $90$ and $124$ inclusive. + +- Subsequently, letting $N = 2N'+1$, $K'$ is randomly selected from integers such that $K = 2K'+1$ satisfies $\left\lceil \sqrt N-1 \right\rceil \le K \le \left\lfloor \sqrt N+4 \right\rfloor$. + +(2) In the Euclidean coordinate plane, let $S$ be a circle centered at the origin with radius $L$. + +(3) Initially, $P = \{(0, 0)\}$. Repeat the following $N'$ times. + +- Select a grid point on or inside the boundary of $S$ and set it as $u=(x_u, y_u)$. + +- If there exists a point $(x_v, y_v) = v \in P$ satisfying one of the following, select $u$ again. $\mathrm{dist}(u, v)$ is the Euclidean distance between point $u$ and $v$. + - $x_u = x_v$ + + - $\mathrm{dist}(u, v) < D$ + +- Add $u$ and $u'$, which is the point reflection of $u$ across the origin $O$, to $P$. + +After the repetition, $|P| = 2N' + 1$. Number the points from $0$ to $N-1$ in increasing order of the $x$ coordinates. + +(4) Draw a circle $C$ centered at the origin $O$ with radius $1.5L$ and divide it into $A$ equal parts. Specifically, let $t_1$ and $t_2$ be the two points where $C$ intersects the $x$ axis. Find the points that divide the upper arc and the lower arc connecting $t_1$ and $t_2$ into $A/2$ equal parts, respectively. Let these points be $Q$. + +(5) Calculate the Voronoi diagram and the Delaunay triangulation based on the points in $P \cup Q$. Collect the centroids of the Voronoi diagram polygons that are dual to each point in $P$ and call this $P'$, and reassign the numbers given to each point. Then, calculate the Voronoi diagram and the Delaunay triangulation based on $P' \cup Q$. + +(6) The Voronoi diagram polygon that is dual to point $t$ becomes area #$t$, and point $t$ becomes the center of area #$t$. If the center of an area is point $u$, that area is adjacent to areas whose centers are points $v \in P$ connected to $u$ in the Delaunay triangulation. Simply put, each area is adjacent to the areas connected by the Delaunay triangulation that were not formed from $Q$. + +(7) Initially, $R = \{N'\}$. Repeat the following $K'$ times. + +- Choose a random $t$ such that $t \in [1, N-2]$ and $t \not \in R$. Areas #$0$ and #$N-1$ cannot be strongholds, since they have the headquarters. + +- If for one or more $r \in R$, area #$t$ or area #$N-1-t$ is adjacent to area #$r$, draw $t$ again. + +- If area #$t$ and area #$N-1-t$ are adjacent, draw $t$ again. + +- Add $t$ and $N-1-t$ to $R$. + +After the iteration, $|R| = 2K' + 1$. For each $r \in R$, area #$r$ is a stronghold. + +
+ +--- + +## Interaction + +Your program must read input from standard input (`stdin`) and follow the protocol of each command. + +#### Ready + +``` +READY (LEFT | RIGHT) +N K +x_{0} ... x_{N-1} +y_{0} ... y_{N-1} +p_{0} ... p_{K-1} +a_{0} b_{0,0} ... b_{0,a_{0}-1} +... +a_{N-1} b_{N-1,0} b_{N-1,1} ... b_{N-1,a_{N-1}-1} +``` + +This command informs the player of the side and the map of the battlefield. + +- The first line indicates which side of Headquarter the player uses. +- The second line contains $N$ and $K$. +- $x_i$ and $y_i$ are the $x$ and $y$-coordinates of the center of area #$i$. +- $p_i$s are the indices of the strongholds. +- Area #$i$ is adjacent to $a_i$ areas. The indices of adjacent areas are given as $b_{i,j}$ ($0 \le j < a_i$). + +Player must output `OK` in $1\,000$ms to indicate the program is ready. Failing to do so results in Time Limit Exceeded(TLE) and forfeits the game. + +#### Command Start + +``` +START TURN T +``` + +At the start of each turn, the `START` command is given. $T$ denotes the day index. + +#### Deliver Command + +``` +COMMAND +... +MOVE a d +TRAIN n +UPGRADE d +... +END +``` + +Player can start the command phase with the `COMMAND` command. Player can submit any number of commands in any order. Then, mark the end of the list with the `END` command. + +The initial warriors are indexed `A1`, `A2`, and `A3` for the left player, and `B1`, `B2`, and `B3` for the right player. + +- `MOVE`: Deliver a Move command to move warrior #$a$ to area #$d$. +- `TRAIN`: Train $n$ warriors at the headquarter. There must be at most $1$ such command in the command phase. +- `UPGRADE`: Upgrade or repair the allied building in area #$d$. If there is no building in area #$d$, build a base instead. + +Player must submit the list within $100$ms after receiving the `START` command (that is, output the `END` command). If more than $100$ms is used, for the exceeded time $t$ms, $\displaystyle \left \lceil \frac{t}{100} \right \rceil$ countdown tokens are consumed. If time is exceeded with no remaining countdown tokens, the player loses by Time Limit Exceeded(TLE). Each player starts with $5$ countdown tokens. + +If an invalid command is submitted, the player immediately loses by Wrong Answer(WA). If invalid commands are submitted at the same time, the game becomes a draw. + +#### View Result + +``` +TURN T +TIME T_x R_x T_y R_y +UPGRADE N +t_1 d_1 +... +TRAIN N +a_1 ... a_N +MOVE N +a_1 d_1 +... +DAMAGE N +C_1 a_1 h_1 +... +SIEGE N +t_1 d_1 h_1 +... +WARRIOR W +a_1 r_1 h_1 +... +BUILDING B +t_1 r_1 k_1 l_1 h_1 +... +``` + +If both players finish submitting commands normally, the result is returned. If $N = 0$ in an `UPGRADE`, `TRAIN`, `MOVE`, `DAMAGE`, or `SIEGE` section, no following line is given for that section. + +- `TURN` $T$: Indicates that information for the current day $T$ is shown. +- `TIME` $T_x$ $R_x$ $T_y$ $R_y$: + - $T_x$ and $T_y$ indicate how much time you and the opponent used this turn, respectively (ms). + - $R_x$ and $R_y$ indicate how many countdown tokens remain for you and the opponent, respectively. +- `UPGRADE` $N$: + - $N$, the number of **allied** buildings built, upgraded, or repaired this turn, is given. + - The next $N$ lines give the $t_i$, `A` or `B`, the owner of the building and $d_i$, the index of area of the building in order. +- `TRAIN` $N$: + - $N$, the number of **allied** warriors trained this turn, is given. + - The next line gives the indices of newly trained warriors in order. Warrior indices are assigned uniquely, increasing sequentially from 1 for each player. + - Warrior indices are always in the form of `A` or `B` followed by an integer (e.g. `A12`, `B7`). If it starts with `A`, it is a warrior of the left player; if it starts with `B`, it is a warrior of the right player. +- `MOVE` $N$: + - $N$, the number of **allied** warriors moved this turn, is given. + - The next $N$ lines give the index $a_i$ of the moved warrior and the index $d_i$ of the area it moved to in order. +- `DAMAGE` $N$: + - $N$, the number of damage records for **allied** warriors this turn, is given. + - The next $N$ lines give the damage cause $C_i$, the index $a_i$ of the damaged warrior, and the damage amount $h_i$ in order. + - $C_i$ is one of the following: `TURRET`(damage by building turret), `COMBAT`(damage by combat between warriors), `HUNGER`(damage by lack of food cost in Supply Step). +- `SIEGE` $N$: + - $N$, the number of damage records for **allied** buildings this turn, is given. + - The next $N$ lines give the building owner $t_i$ ($t_i$ is `A` or `B`), area #$d_i$ of the damaged building, and the siege damage amount $h_i$ in order. +- `WARRIOR` $W$: + - $W$, the number of **all** warriors currently in vision, is given. + - The next $W$ lines give the index $a_i$ of the warrior, the index $r_i$ of the area it is located in, and its current HP $h_i$ in order. +- `BUILDING` $B$: + - $B$, the number of **all** buildings currently in vision, is given. + - The next $B$ lines give the building owner $t_i$ (`A` or `B`), the index $r_i$ of the area it is located in, its type $k_i$ (`HQ` or `BASE`), its level $l_i$, and its current HP $h_i$ in order. + +The result of each turn ends with the `END` command. + +### Game End + +``` +FINISH +``` + +When the game ends for any reason, the `FINISH` command is given. **When this command is received, the program must immediately terminate gracefully regardless of the game state.** In other words, if the `FINISH` command is given instead of the result after a turn ends, the program must immediately terminate before trying to read the result. + +## Game Simulator + +[Go to Simulator](https://d1thb30t7rs13h.cloudfront.net/) + +You can paste logs into the simulator above to analyze game play. + +## CLI Tool + +[Download CLI Tool](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/nation-fr-providing.zip) + +You can use the CLI tool above to have AIs play against each other locally. + +## Sample Code + +Sample code written in each supported language is available below. + +- C: [sample-code.c](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.c) +- C++: [sample-code.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.cpp) +- Python: [sample-code.py](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.py) +- Rust: [sample-code.rs](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.rs) +- Java: [Main.java](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/Main.java) +- JavaScript: [sample-code.js](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.js) +- TypeScript: [sample-code.ts](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.ts) +- C#: [sample-code.cs](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.cs) +- Kotlin: [sample-code.kt](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.kt) +- Go: [sample-code.go](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.go) +- Scala: [sample-code.scala](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.scala) +- Lua: [sample-code.lua](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-code/sample-code.lua) + +## Sample AI + +| Battle Number | Description | Sample AI | +| :-----------: | :---------------------------------- | :--------------------------------------------------------------------------------------------------------------------------- | +| 1 | Employs a basic offensive strategy. | [1_rush.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/1_rush.cpp) | +| 2 | Employs a basic ambush strategy. | [2_ambush.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/2_ambush.cpp) | +| 3 | Employs a basic balanced strategy. | [3_deathball.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/3_deathball.cpp) | +| 4 | Employs a basic vigilant strategy. | [4_blockade.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/4_blockade.cpp) | +| 5 | Employs a basic defensive strategy. | [5_eco.cpp](https://nypc-static.s3.ap-northeast-2.amazonaws.com/2026/nextnation-fr-0cxj73lq/sample-ai/5_eco.cpp) | + +> Note: Sample AI codes were not provided during the actual contest. diff --git a/src/routes/en/2026/index.tsx b/src/routes/en/2026/index.tsx index 1c8130dc8..db9701bee 100644 --- a/src/routes/en/2026/index.tsx +++ b/src/routes/en/2026/index.tsx @@ -5,6 +5,7 @@ const year = 2026; export const problems = { master: [["pre_m", "NEXT NATION"]], + masterFinal: [["final_m", "NEXT VISION"]], } as const; const List = () => { @@ -20,6 +21,10 @@ const List = () => { Master Track — Qualification Round + + Master Track — Final Round + + ); }; diff --git a/src/routes/en/2026/pre_m.mdx b/src/routes/en/2026/pre_m.mdx index 8cb78f75e..e71e1343c 100644 --- a/src/routes/en/2026/pre_m.mdx +++ b/src/routes/en/2026/pre_m.mdx @@ -9,8 +9,6 @@ stage: Master Track Qualification Round -
-

## Rules @@ -58,12 +56,8 @@ The Evening consists of **Labor Step** → **Supply Step**, in order. - In the **Labor Step**, each building produces $15 \times x$ gold, where $x$ is the minimum value of `# of allied warriors in the area` and `# of labor slots`. - In the **Supply Step**, each warrior consumes $2$ gold in increasing order of number. If there is not enough gold when a warrior tries to consume gold, the warrior loses 1 HP. If the HP of the warrior becomes 0, the warrior retreats, leaving the battlefield. -
- --- -
- ### 2 | Building Buildings are the source of income. @@ -87,8 +81,6 @@ Each player starts with a headquarter of level $1$. Only one headquarter is allo | $5$ | $3\,600$ gold | $8$ | $30$ | $3$ | $3$ | $5$ | | $5+$ (Repair) | $1\,000$ gold | - | - | - | - | - | -
- #### Base Each player can build as many bases as they want. Unlike headquarter, warriors cannot be trained on base. @@ -100,12 +92,8 @@ Each player can build as many bases as they want. Unlike headquarter, warriors c | $3$ | $1\,000$ gold | $18$ | $2$ | $3$ | | $3+$ (Repair) | $500$ gold | - | - | - | -
- --- -
- ### 3 | Movement and Battle #### Movement Rule @@ -134,12 +122,8 @@ The rule of each attack is as follows: - Among the opponent's warriors with positive HP, decrease the HP of the warrior with minimum HP by 1. If multiple such warriors exist, the warrior with the lowest number is targeted. - If there is no opponent's warrior with positive HP, and the opponent's building has positive HP, the HP of the opponent's building is decreased by 1. -
- --- -
- ### 4 | Game End During $200$ days from the game start, if the Headquarter is destroyed, then the player whose Headquarter is not destroyed wins. @@ -148,12 +132,8 @@ If two headquarters are destroyed on the same day, or both headquarters are not If the HP of two HQ are equal, then the game ends in a draw. -
- --- -
- ### 5 | Detailed Rules: Battlefield Generation Method Since the structure of the battlefield is given as input, you do not need to know the generation rules to solve the problem. @@ -217,8 +197,6 @@ After the iteration, $|R| = 2K' + 1$. For each $r \in R$, area #$r$ is a strongh -
- --- ## Interaction