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 并行博弈(博弈论)的主要内容,如果未能解决你的问题,请参考以下文章

2021.8.13提高B组模拟5T1 Brothers(暴力)

2021.7.16提高B组模拟5T2 图书馆(dp)

jzoj3552WC2014模拟2.6结论题并行博弈

[CSP-S模拟测试]:取石子(博弈论+DP)

2017.12.09NOIP提高组模拟赛A组

2017.07.16【NOIP提高组】模拟赛B组 卫星照片 题解