https://vjudge.net/contest/454885#problem/B
题意:
n ∗ m 的棋盘,每个位置 1 个数字,初始 ( 1 , 1 )
R 和 K 轮流操作,R可以将棋子移动到同一行的任何位置(可以原位置),K 可以将棋子移动到同一列的任何位置
游戏进行 k 轮,也可以在每一轮操作前 R 或 K 选择结束游戏,结束的位置的数值为最终价值
R 想最大化价值,K 反之
两人都是最优策略,求最终价值
思路:
显然是一个博弈题
考虑先手 R :因为 K 是同一列最小化,所以 R 最优策略会移动到 同列上最小值 最大 的那一列(有个前提,K 还能进行下一轮操作)
考虑后手 K :同上理,最优策略会移动到 同行上最大值 最小 的那一行(有个前提,R 还能进行下一轮操作)
若不是随时结束
当 k 为奇数时,最后操作的是 R ,答案便是 同行上最大值 最小 那一行的最大值
当 k 为偶数时,最后操作的是 K ,答案便是 同列上最小值 最大 那一列的最小值
现考虑随时结束:先手已知不结束的最优值,只需和最初值比较一下,输出大的即可
代码
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll n, m, k;
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%lld %lld %lld", &n, &m, &k);
vector<vector<ll>>q(n, vector<ll>(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%lld", &q[i][j]);
}
}
vector<ll> rmx(n, 0), cmn(m, 0x3f3f3f3f);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
rmx[i] = max(rmx[i], q[i][j]);
cmn[j] = min(cmn[j], q[i][j]);
}
}
if (k == 1) {
printf("%lld\n", rmx[0]);
}
else if ( k % 2 != 0) {
ll ans = max(q[0][0], *min_element(rmx.begin(), rmx.end()));
printf("%lld\n", ans);
}
else {
ll ans = max(q[0][0], *max_element(cmn.begin(), cmn.end()));
printf("%lld\n", ans);
}
}
return 0;
}