試題 歷屆試題 填字母遊戲
資源限制
時間限制:1.0s 內存限制:256.0MB
問題描述
小明經常玩 LOL 遊戲上癮,一次他想挑戰K大師,不料K大師說:
“我們先來玩個空格填字母的遊戲,要是你不能贏我,就再別玩LOL了”。
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
以前寫過類似的沒理解透,遇到這題還是一臉懵。。。
題目說小明先填,當K大師總是用最強着法的時候,小明的最好結果。,這就是兩個人都要希望有最好的結果,而遞歸能很好的解決這個問題,遞歸可以實現兩個人輪流填,每次返回都是最優解。因爲小明先填,遞歸最後一次返回的就是先填的,就是小明的結果。
#include <bits/stdc++.h>
using namespace std;
const int N=1005;
const int inf=0x3f3f3f3f;
map<string,int>mp;
string s;
int dfs(){
if(mp.count(s)) return mp[s];
if(s.find("LOL")!=-1) return -1;
if(s.find("*")==-1) return 0;
int i,flag=0,t;//flag平局
for(i=0;i<s.size();i++){
if(s[i]=='*'){
s[i]='L';
t=dfs();
s[i]='*';
if(t==-1) return mp[s]=1;
if(t==0) flag=1;
s[i]='O';
t=dfs();
s[i]='*';
if(t==-1) return mp[s]=1;
if(t==0) flag=1;
}
}
if(flag) return mp[s]=0;
return mp[s]=-1;
}
int main()
{
int n;
scanf("%d",&n);
while(n--){
cin>>s;
printf("%d\n",dfs());
}
return 0;
}