[信息与未来 2026] 桌面游戏
数字顺序固定,真正要搜索的是“当前数字放哪个空格”。
一、先回答问题
结论
用极小化极大:Dr. X 让最终 `x-y` 尽量大,Dr. Y 让最终 `x-y` 尽量小。
课堂安排
先抓住模型,再用一个小样例手推,最后把判断写成稳定的 C++14 代码。
二、核心观察
搜索层
第 t 层放剩余数字中的第 t 个。
决策
偶数层取 max,奇数层取 min。
三、互动演示
XY算分
四、自己选答案
问题 1:这题最关键的状态是什么?
五、手推结果
| 函数 | 作用 |
|---|---|
| `dfs(t)` | 从第 t 个剩余数字开始,双方最优后的最终分差 |
| `score()` | 计算三行乘积和减三列乘积和 |
| `memo` | 记忆化相同局面 |
六、C++14 参考代码
#include <bits/stdc++.h>
using namespace std;
int a[9];
vector<int> nums;
unordered_map<string, int> memo;
int score() {
int x = 0, y = 0;
for (int i = 0; i < 3; i++) {
x += a[i * 3] * a[i * 3 + 1] * a[i * 3 + 2];
y += a[i] * a[i + 3] * a[i + 6];
}
return x - y;
}
string key(int t) {
string s;
s.reserve(10);
s.push_back(char('0' + t));
for (int i = 0; i < 9; i++) s.push_back(char('0' + a[i]));
return s;
}
int dfs(int t) {
if (t == (int)nums.size()) return score();
string k = key(t);
if (memo.count(k)) return memo[k];
int cur = nums[t];
if (t % 2 == 0) { // Dr. X: maximize x-y
int res = -1e9;
for (int i = 0; i < 9; i++) {
if (a[i] == 0) {
a[i] = cur;
res = max(res, dfs(t + 1));
a[i] = 0;
}
}
return memo[k] = res;
} else { // Dr. Y: minimize x-y
int res = 1e9;
for (int i = 0; i < 9; i++) {
if (a[i] == 0) {
a[i] = cur;
res = min(res, dfs(t + 1));
a[i] = 0;
}
}
return memo[k] = res;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
bool used[10] = {};
for (int i = 0; i < 9; i++) {
cin >> a[i];
if (a[i]) used[a[i]] = true;
}
nums.clear();
for (int x = 1; x <= 9; x++) {
if (!used[x]) nums.push_back(x);
}
memo.clear();
int diff = dfs(0);
if (diff > 0) cout << "first\n";
else if (diff < 0) cout << "second\n";
else cout << "tie\n";
}
return 0;
}读代码重点
先看状态变量,再看核心判断,最后检查边界和输出格式。