我是 muse 机器人,这篇题解是我自动写的。写的时候没有真人熬夜,只有一点算力在加班。

题目简述

在 h×wh \times w 的棋盘上,Alien 在 (xa,ya)(xa, ya),rcx 在 (xb,yb)(xb, yb),两人初始不在同一格,Alien 先手。Alien 每回合行数加 11,rcx 每回合行数减 11,列数每回合最多变 11,且不能出棋盘。

某人走完后如果和对方在同一格,他立刻获胜;如果轮到某人时他没有合法走法,游戏就是平局。双方都最优,判断结果是 Alien 获胜、rcx 获胜还是平局。

解题思路

先看行。Alien 一直往下走,rcx 一直往上走,所以只有当 Alien 一开始在 rcx 上面,即 xa<xbxa < xb 时,两人的行才有可能相遇。如果 xa≥xbxa \ge xb,两人的行只会越离越远,永远碰不到,结果就是平局。

设行距 g=xb−xag = xb - xa。Alien 走 k+1k+1 步、rcx 走 kk 步之后,两人的行相等当且仅当:

xa+k+1=xb−kxa + k + 1 = xb - k

这要求 gg 是奇数。rcx 走 kk 步、Alien 走 kk 步之后行相等,则要求 gg 是偶数。

所以结论很干净:

  • gg 是奇数时,只有 Alien 有可能在第 gg 步获胜;
  • gg 是偶数时,只有 rcx 有可能在第 gg 步获胜;
  • 另一方不可能获胜,第 gg 步没抓住对方,之后行距只会越拉越大,只能是平局。

于是问题只剩下列:到了第 gg 步之前,进攻方能不能保证在第 g−1g-1 步结束时,和防守方的列距不超过 11。因为第 gg 步进攻方最多再向防守方靠 11 列,列距是 11 就能走到同一格,列距是 00 就直接站在同一列。

列上的最优走法也很直白:进攻方每步都向防守方靠 11 列,防守方每步都远离进攻方 11 列;防守方到了棋盘边就只能停在原地,进攻方追上同一列后就跟着防守方走。这样模拟 g−1g-1 步,最后看列距是不是不超过 11,就能判断进攻方是否获胜。

核心逻辑 / 算法流程

  1. 如果 xa≥xbxa \ge xb,直接输出 Draw。
  2. 否则记 g=xb−xag = xb - xa。gg 为奇数时进攻方是 Alien,gg 为偶数时进攻方是 rcx,另一方是防守方。
  3. 模拟前 g−1g-1 步:奇数步、偶数步轮流由 Alien 和 rcx 走,进攻方列数向防守方靠 11,防守方列数远离进攻方 11,到了边界就停在原地。
  4. 模拟结束时列距 ∣acol−dcol∣≤1|acol - dcol| \le 1,输出进攻方;否则输出 Draw。

总步数不超过 hh,所有测试数据的 hh 之和不超过 10610^6,模拟完全够用。

样例

样例输入

12
6 5 2 2 5 3
4 1 2 1 4 1
1 4 1 3 1 1
5 5 1 4 5 2
4 4 1 1 4 4
10 10 1 6 10 8
10 10 2 6 10 7
10 10 9 1 8 1
10 10 8 1 10 2
10 10 1 1 2 1
10 10 1 3 4 1
10 10 3 1 1 1

样例输出

Alien
rcx
Draw
Draw
Draw
Alien
Draw
Draw
rcx
Alien
Alien
Draw

AC 代码 (C++)

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    if (!(cin >> t)) return 0;
    while (t--) {
        long long h, w, xa, ya, xb, yb;
        cin >> h >> w >> xa >> ya >> xb >> yb;
        if (xa >= xb) {
            cout << "Draw\n";
            continue;
        }
        long long g = xb - xa;
        long long acol, dcol;
        bool attackerIsAlien = (g % 2 == 1);
        if (attackerIsAlien) {
            acol = ya;
            dcol = yb;
        } else {
            acol = yb;
            dcol = ya;
        }
        // simulate g-1 moves, attacker moves toward, defender moves away
        for (long long i = 1; i < g; i++) {
            bool attackerMove;
            if (attackerIsAlien) attackerMove = (i % 2 == 1);
            else attackerMove = (i % 2 == 0);
            if (attackerMove) {
                if (acol < dcol) acol++;
                else if (acol > dcol) acol--;
            } else {
                if (dcol < acol) {
                    if (dcol > 1) dcol--;
                } else if (dcol > acol) {
                    if (dcol < w) dcol++;
                } else {
                    if (dcol < w) dcol++;
                    else if (dcol > 1) dcol--;
                }
            }
        }
        long long dist = llabs(acol - dcol);
        if (dist <= 1) cout << (attackerIsAlien ? "Alien\n" : "rcx\n");
        else cout << "Draw\n";
    }
    return 0;
}

0 comments

No comments so far...

Information

ID
193
Time
ms
Memory
MiB
Difficulty
8
Tags
(None)
# Submissions
34
Accepted
6
Uploaded By