hdu 7067 Just another board game
题意:
-
n ∗ m n*m n∗m 的棋盘,每个位置 1 1 1 个数字,初始 ( 1 , 1 ) (1,1) (1,1)
R R R 和 K K K 轮流操作,R可以将棋子移动到同一行的任何位置(可以原位置), K K K可以将棋子移动到同一列的任何位置
-
游戏进行 k k k 轮,也可以在每一轮操作前 R R R 或 K K K选择结束游戏,结束的位置的数值为最终价值
R R R 想最大化价值, K K K 反之
-
两人都是最优策略,求最终价值
思路:
-
显然是一个博弈题
-
考虑先手 R R R :因为 K K K 是同一列最小化,所以 R R R 最优策略会移动到 同列上最小值 最大 的那一列(有个前提, K K K 还能进行下一轮操作)
-
考虑后手 K K K :同上理,最优策略会移动到 同行上最大值 最小 的那一行(有个前提, R R R 还能进行下一轮操作)
-
若不是随时结束
- 当 k k k 为奇数时,最后操作的是 R R R,答案便是 同行上最大值 最小 那一行的最大值
- 当 k k k 为偶数时,最后操作的是 K K K,答案便是 同列上最小值 最大 那一列的最小值
-
现考虑随时结束:先手已知不结束的最优值,只需和最初值比较一下,输出大的即可
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int mx[N], mn[N];
signed main()
{
ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int T;
cin>>T;
while(T--)
{
int n,m,k;
cin>>n>>m>>k;
int a[n+5][m+5];
for(int i=1;i<=n;i++)
{
mx[i]=0;
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
mx[i] = max(mx[i], a[i][j]); // 同行最大值
}
}
if(k==1) { cout<<mx[1]<<endl; continue; } // 1要特判
for(int i=1;i<=m;i++) mn[i] = 1e10;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
mn[j] = min(mn[j], a[i][j]); // 同列最小值
}
}
int mnx=1e10, mxy=0;
for(int i=1;i<=n;i++) mnx = min(mnx,mx[i]); // 取同行最大值的最小
for(int i=1;i<=m;i++) mxy = max(mxy,mn[i]); // 取同列最小值的最大
if(k%2==0) cout<<max(mxy,a[1][1])<<endl;
else cout<<max(mnx, a[1][1])<<endl;
}
return 0;
}