2021.7.16提高B组模拟5T1 并行博弈(博弈论)
Posted SSL_LKJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.7.16提高B组模拟5T1 并行博弈(博弈论)相关的知识,希望对你有一定的参考价值。
并行博弈
题目大意
lyp和ld在一个n*m的棋盘上玩翻转棋,游戏棋盘坐标假设为(x, y),1 ≤ x ≤ n,1 ≤ y ≤ m,这个游戏的规则如下:
每次可以操作坐标为 (x, y) 的棋子,要求棋子 (x, y) 必须是黑色,并且同时翻转所有棋子坐标 (x’, y’) 满足 x’≤x, y’≤y。
lyp觉得这样还不够过瘾,于是乎他打算同时玩 k 个这样的游戏, 每次可以对其中某一个游戏进行操作,lyp先手,ld后手,两人轮流进行操作,最后无法进行操作的人判输,现在给你这个游戏的局面,要求输出是先手必胜(“lyp win”)还是后手必胜(“ld win”)。
输入样例
1
1
2 2
1 1
1 0
输出样例
lyp win
解题思路
1.大致思路
这是道经典的博弈题目
根据题目样例可知
棋盘是这样的
1 1
1 0
我们不难可以发现
不管我们动哪个黑棋
最左上角的棋子都会被改变
所以当一开始左上角的棋子为黑子时
先手 lyp 就可以翻它,变为白
到 ld 翻其他棋子的时候
这个棋又变黑了
这样 lyp 又可以翻回去
lyp 就会赢
反之,左上角棋子开始为白子时
ld 就会赢
2.多个游戏同时
我们可以将这个问题转换一下
一个游戏接着一个游戏来
因为如果第一把是 先手 lyp 赢
则下一把的 先手 则是 上一把的 后手 ld
那这样之后
就不难得出答案
AC代码
#include<cstdio>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int K,ans=-1,thisfirst=1;
//ans表示谁赢,如果一开始就动不了则 ld 赢
//thisfirst 表示先手是谁 1 表示 lyp -1 表示 ld ,好转换
scanf("%d",&K);
for(int k=1;k<=K;k++)
{
int n,m,ok=1;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
int x;
scanf("%d",&x);
if(i==1&&j==1&&x==1)ok=0;//判断左上角
}
if(ok)ans=-thisfirst;
//判断,如果为 0 ,则 后手 赢,下把的 先手 和这把还是一样
else
{
ans=thisfirst;
thisfirst=-thisfirst;
}
//为 1 则切换
}
if(ans==1)printf("lyp win\\n");
else printf("ld win\\n");
}
return 0;
}
谢谢
以上是关于2021.7.16提高B组模拟5T1 并行博弈(博弈论)的主要内容,如果未能解决你的问题,请参考以下文章