藍橋杯-填字母游戲(無偏博弈類問題)


問題描述:

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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM