Just another board game
算法:博弈论,思维
Problem Description
After playing some games of Go, Roundgod and kimoyami decide to try something different. Now they are playing a new kind of game on a chessboard. The chessboard is a grid board with n rows and m columns. We assume that the upper left corner of the chessboard has coordinate (1,1), and the lower right corner of the chessboard has coordinate (n,m). There’s a number on every grid of the board, with the number written on the grid on the ith row and jth column equal to aij. What’s more, there’s a chess piece on the upper left corner(i.e., (1,1)) of the chessboard initially. Now the two players take turns to choose one of the following operations, starting from Roundgod:
- Move the chess piece. If it’s Roundgod’s turn, he can move the chess
piece to any position in the same row(It’s also OK to move it to the
current position, i.e., not moving it at all). If it’s kimoyami’s
turn, he can move the chess piece to any position in the same column.
(It’s also OK to move it to the current position, i.e., not moving it
at all) - Screw it. I’m going home. Finish the game immediately.
The game ends when either of the two players chooses the second operation or when the game has already been going on for k turns. (Either of the two players’ operations counts as one turn). The value of the game is defined as the number on the grid where the chess piece lands when the game ends. Now, Roundgod wants to maximize this value, while kimoyami wants to minimize this value. They don’t have the patience to actually play this game for possibly that many turns, so they want you to calculate what will be the final value of the game if both players choose the optimal strategy?
注释:
- 首先应该注意到,移动任意两步即可到达本土的任意位置,所以除了最后两步外,其余的步骤都是多余的,也就是说在最后两步之前到达的位置都是等价的。
- 现在来考虑,当最后一步是B走,也就是k为偶数时,A的倒数第二步应该走到某一列的最小值应该尽量大,才能使得最后的值尽量大,否则一定更小;当最后一步是A走,也就是k为奇数时,B的倒数第二步应该走到某一列的最大值应该尽量小,才能使得最后的值尽量小,否则一定更大;应该注意的是,如果k为偶数时,得到的最终值比第一个数字更小的话,则A可以直接结束游戏。
- 再来考虑使用第二种策略,很明显第二种策略是不明智的,在对手移动后选择结束都是不明智的,因为对手不会选择一种让你可以直接结束的步骤。
- 博弈论的题目应认真考虑其中的矛盾关系,通过缩减步骤,减少考虑,考虑控制关系总有一种策略是明确的。
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#define INF 1e9+10
#define N 100010
using namespace std;
struct p{
int x;
int y;
bool state;
}q[N*20];
struct point{
int val;
int num;
}maxr[N],minl[N];
int n,m,k,head,tail,step;
vector<int>a[N];
vector<bool>vis[2][N];
void init(int n)
{
head=tail=step=0;
for(int i=0;i<=n;i++)
{
a[i].clear();
vis[0][i].clear();
vis[1][i].clear();
}
}
int main()
{
int t,x;
scanf("%d",&t);
while(t--)
{
step=0;
scanf("%d%d%d",&n,&m,&k);
init(n);
for(int i=0;i<n;i++)
{
maxr[i].val=-1;
for(int j=0;j<m;j++)
{
scanf("%d",&x);
a[i].push_back(x);
vis[1][i].push_back(0);
vis[0][i].push_back(0);
if(maxr[i].val<x)
{
maxr[i].num=j;
maxr[i].val=x;
}
}
}
for(int i=0;i<m;i++)
{
minl[i].val=INF;
for(int j=0;j<n;j++)
{
if(minl[i].val>a[j][i])
{
minl[i].val=a[j][i];
minl[i].num=j;
}
if(minl[i].val==a[j][i])
{
minl[i].num=(maxr[minl[i].num].val>maxr[j].val?j:minl[i].num);
}
}
}
int maxn=a[0][0];
if(k==1)maxn=maxr[0].val;
else if(k%2)
{
for(int i=0;i<n;i++)
maxn=min(maxn,maxr[i].val);
maxn=max(a[0][0],maxn);
}
else if(k%2==0)
{
for(int i=0;i<m;i++)
maxn=max(maxn,minl[i].val);
}
printf("%d\n",maxn);
}
return 0;
}