Just another board game
题意:
一棋子初始位于(1,1),A先手,A可以横移棋子,B可以竖移棋子,或者,到某人行动的时候可以立刻终止游戏。游戏执行k轮后会结束。最终棋子停留的底下的值为最终得分,A目标是最大化,B目标是最小化。求最终答案。
结论:
k
=
1
k=1
k=1 时显然,答案为第一行的最大值
k
k
k 为偶数,答案为
m
a
x
(
a
1
,
1
,
m
a
x
i
=
1
m
c
i
)
max(a_{1,1},max_{i=1}^m\,c_i)
max(a1,1,maxi=1mci)
k
k
k 为奇数,答案为
m
i
n
(
a
1
,
1
,
m
i
n
i
=
1
n
r
i
)
min(a_{1,1},min_{i=1}^n\,r_i)
min(a1,1,mini=1nri)
推理:
不考虑直接结束游戏的操作:
当
k
=
1
k=1
k=1 时,取第一行最大值
当
k
>
=
2
k>=2
k>=2 时,无论
k
k
k 取多大,我们只需要考虑最后两步即可(从最后往前推可以发现这个结论
当
k
k
k 为奇数,最后一步是先手 A,那么他会落到这一行中最大值的位置,B为了让这个最大值尽可能小,B肯定会在上一步选择所有行中最大值最小的一行。
当
k
k
k 为偶数,最后一步是后手B,那么他会落到这一列中最小值的位置,A为了让这个最小值尽可能大,A肯定会在上一步选择所有列中最小值最大的一列。
考虑直接结束游戏的操作:
如果
a
1
,
1
a_{1,1}
a1,1 最大,先手可以直接结束游戏得到最大值
而无论
k
k
k 等于多少,每一步都会达到一个最值,终止游戏只会使得当前结果不符合自己结果
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 9;
ll n, m, k;
ll r[maxn], c[maxn];// r维护所有行中最大值,c所有列中最小值
void work()
{
cin >> n >> m >> k;
for(int i = 1; i <= n; ++i)
r[i] = 0;
for(int i = 1; i <= m; ++i)
c[i] = (int)1e9;
ll y;// 存 a_{1,1}
for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j)
{
ll x;cin >> x;
if(i == 1 && j == 1) y = x;
r[i] = max(x, r[i]);
c[j] = min(x, c[j]);//
}
ll ans = 0;
if(k == 1){
cout << r[1] << endl;return;
}
else if(k & 1)
{
ans = 1e9;
for(int i = 1; i <= n; ++i)
ans = min(ans, r[i]);// B操作使得A只能选所有行中最大值最小的一个
}
else
{
for(int i = 1; i <= m; ++i)
ans = max(ans, c[i]);// A操作使得B只能选所有列中最小值最大的一个
}
cout << max(ans, y) << endl;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T;cin>>T;while(T--)
work();
return 0;
}