試題 歷屆試題 填字母遊戲(博弈)

試題 歷屆試題 填字母遊戲

資源限制
時間限制: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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章