博弈论B1. Palindrome Game (easy version)—— Codeforces Round #721 (Div. 2)

Posted 出尘呢

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了博弈论B1. Palindrome Game (easy version)—— Codeforces Round #721 (Div. 2)相关的知识,希望对你有一定的参考价值。

本题有难易两个版本。

easy version:
https://codeforces.com/contest/1527/problem/B1

/*
当0, B,差1
当00,B,差2
当000,A,中间多1,但最后少2
对于00,A1B1可以
讨论:
eke——只有中间一个0的时候,bob赢。0个数是偶数时,alice每次放一个,bob就放对称,最后一对0,alice填了一个给bob的时候bob不放,这样bob总是比alice少填2个
为奇数的时候,alice填中间那个,把偶数的时候alice面对的状态转移给bob,这样alice总是比bob少填2-1个
b2应该是先让bob把所有非回文的地方补上,昨天晚上太混乱了
灵儿——哦意思就是博弈论能赢就行,不是贪心解法…
我想0个数是偶数时,alice每次放一个,bob就翻一下,alice再放一个对称,bob变成了alice,就乱七八糟的混乱w
其实不面对对称的优势值2分,这样就够了w之后像nim一样在平手情况下,维持这样的优势,躺赢
*/

小错误:
//这里小输入符错!
//注意初始化!

#include<bits/stdc++.h>
#ifdef LOCAL
FILE*FP=freopen("text.in","r",stdin);
#endif
using namespace std;

char str[1003];
void get(int&a,int&b,int&n){
	scanf("%d",&n);
	scanf("%s",str);//这里小输入符错! 
	a=0,b=0;//注意初始化! 
	for(int i=0;i<n/2;i++){
//		printf("%c %c\\n",str[i],str[n-i-1]);
		if(str[i]=='0'&&str[n-i-1]=='0')a++;
	}
	if(n%2&&str[n/2]=='0')b++;
//	printf("in:%d %d %d\\n",a,b,n);
}
signed main(){
	int t,n,a,b;//对称,中间 
	scanf("%d",&t);
	int flag=0;//1a2b
	while(t--){
		get(a,b,n);
//		printf("%d %d %d\\n",a,b,n);
		if(b==0||a==0)flag=2;
		else flag=1;
		printf("%s\\n",(flag==1)?"ALICE":"BOB");
	}
	return 0;
}

hard version:
有之前的经验,多讨论一下
从A先手希望取胜的方面讨论,首先先手有优势的话保持就是了,这就是关键,从先手的角度看策略。

如何保持先手优势,减小问题规模:

对称00

A只能填一个,B填另一个,不变,平手
谁能让对手处在对称00,其实是占优的
因为A只能填一个,B也可以翻转,则A,-2,而让对方处于这个情况对调了,其实还是A想这样化回来,B被动就有被平手的可能。所以B选择走最小的步长,掌控时机让A-2时刚好下完
——后手胜,-2

不对称0011

A翻转,B填,不变,A+1
——先手胜,+m

有中0:

只有中0:

A只能取之,-1,负

此外只有对称0:

A取中0,-1,之后可保证+2,整体+1,所以必胜

此外只有m个不对称0:

A不要白不要(理解一下不要是不是白不要了)
所以让B填m个,+m,之后自己来填最后一个,-1,最少了,整体m-1
m=1,平,m>1,胜

有对称0和不对称0:

A先白要m个,+m,并且还是到了此外只有对称0,能必胜

无中0:

只有对称0:

即对称00情况
——A负

只有不对称0:

即不对称0011情况
——A胜

有对称0和不对称0:

A要先享受不对称0优势,B填也不会去填对称0创造更多不对称0,A有m-1分
之后A填了最后的不对称0,把对称00局面给了B,A有2分
——整体m-1分,A胜

下结论

为了最后判断,按胜负总结,不是去一个个寻找那么多情况是不是匹配

A负:

1.只有中间0
2.只有对称0

A平:

1.只有(中间0和一个不对称0)

A胜:

1.有中0,有对称0
2.有中0,有多于一个不对称0
3.无中0,有不对称0

#include<bits/stdc++.h>
#ifdef LOCAL
FILE*FP=freopen("text.in","r",stdin);
#endif
using namespace std;
char str[1003];
void get(int&f1,int&f2,int&f3,int&n){
	f1=f2=f3=n=0; 
	scanf("%d",&n);
	scanf("%s",str);
	if(n%2&&str[n/2]=='0')f1=1;//有中0 
	for(int i=0;i<n/2;i++){
		//printf("%c %c\\n",str[i],str[n-i-1]);
		if(str[i]=='0'&&str[n-i-1]=='0')f2++;//对称0 
		if(str[i]!=str[n-i-1])f3++;
	}
	//printf("in:%d %d %d\\n",f1,f2,f3);
}
signed main(){
	int t,n,f1,f2,f3,f;//中间, 对称, 不对称 //f:a1胜2负3平 
	scanf("%d",&t);
	while(t--){
		get(f1,f2,f3,n);
		//printf("%d %d %d\\n",f1,f2,f3);
		if((f1&&!f2&&!f3)||(f2&&!f1&&!f3))f=2;
		else if(f1&&f3==1&&!f2)f=3;
		else f=1;
		if(f==1)printf("ALICE\\n");
		if(f==2)printf("BOB\\n");
		if(f==3)printf("DRAW\\n");
	}
	return 0;
}

以上是关于博弈论B1. Palindrome Game (easy version)—— Codeforces Round #721 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #721 (Div. 2)B1. Palindrome Game (easy version)B2. Palindrome Game (hard version)题解

Codeforces Round #721 (Div. 2)A. And Then There Were K(位运算,二进制) B1. Palindrome Game (easy version)(

题解——POJ 2234 Matches Game

博弈论Multiplication Game

Multiplication Game(博弈论)

博弈论Euclid's Game