蓝桥杯-填字母游戏(无偏博弈类问题)

问题描述:

K大师在纸上画了一行n个格子,要小明和他交替往其中填入字母。
1. 轮到某人填的时候,只能在某个空格中填入L或O
2. 谁先让字母组成了“LOL”的字样,谁获胜。
3. 如果所有格子都填满了,仍无法组成LOL,则平局。

小明试验了几次都输了,他很惭愧,希望你能用计算机帮他解开这个谜。

本题的输入格式为:
第一行,数字n(n<10),表示下面有n个初始局面。
接下来,n行,每行一个串,表示开始的局面。
  比如:“******”, 表示有6个空格。“L****”,   表示左边是一个字母L,它的右边是4个空格。

要求输出n个数字,表示对每个局面,如果小明先填,当K大师总是用最强着法的时候,小明的最好结果。
1 表示能赢
-1 表示必输
0 表示可以逼平

输入

4
***
L**L
L**L***L
L*****L

输出

0
-1
1
1

问题分析:

  首先,对于此问题,我们要明白,它是有偏博弈,还是无偏博弈。

  无偏博弈:在组合博弈论里,无偏博弈是一类任意局势对于游戏双方都是平等的回合制双人游戏。这里平等的意思是所有可行的走法仅仅依赖于当前的局势,而与现在正要行动的是哪一方无关。换句话说,两个游戏者除了先后手之外毫无区别。

  有偏博弈:除无偏博弈外,其余博弈皆为有偏博弈

  当填入一个字母时,我们要考虑两个问题,一是是否形成了LOL这个字符串,二是是否还存在空格,如果是第一种情况,则说明对方输了,我方赢了,如果不存在空格了,说明将有可能平局,因此,问题就简化为对每一个要填的空,做上述的判断,形成了一个递归。

代码描述:

  

/*LOL填字游戏
我方先填 
*/
#include<iostream>
#include<cstdlib>
#include<string> 
using namespace std;
int is_lol(string x); 

int main(){
    string x;
    cout<<is_lol("***")<<endl;
    cout<<is_lol("L**L")<<endl;
    cout<<is_lol("L**L***L")<<endl;
    cout<<is_lol("L*****L")<<endl;
    return 0;
} 
int is_lol(string x){
    /*1表示能赢
    0表示平局 
    -1表示输 
    */
    int len=x.length(); 
    if(x.find("LOL")!=string::npos) return -1;//当我方开始填时已出现LOL时,则我方输 
    if(x.find("*")==string::npos) return 0;//当没有出现LOL时,且没有空格则为平局 
    int ping=0;//先假设为平局 
    for(int i=0;i<len;i++){
        if(x[i]=='*'){
            x[i]='L';
            switch(is_lol(x))
            {
                case -1: return 1;//当我方填完后,出现LOL,则我方赢 
                case 0: ping=1;//当我方填完后,没有空格,则为平局 
            }
            x[i]='O';
                switch(is_lol(x))
            {
                case -1: return 1;//当我方填完后,出现LOL,则我方赢 
                case 0: ping=1;//当我方填完后,没有空格,则为平局 
            }
            x[i]='*';
    }
    }
    if(ping) return 0;//如果存在平局,则结果为平局,否则即输 
    return -1;
}

 

posted @ 2018-03-21 20:18  Do_Better  阅读(2569)  评论(1编辑  收藏  举报