CCF CSP 201803-4 棋局评估(博弈问题)

思路:

1.基本思想就是暴力,枚举每一种可能情况,利用决策树进行对抗搜索;
2.Alice搜索时,选取所有返回值里最大的那个,Bob相反;
3.也可以用记忆化搜索进行优化,我用的string保存棋盘,用unordered_map保存每一次结果即可;
4.这题用getchar就翻车 = = ,本地调试都过了提交一分都没有,说明后台压根没按题目上给的格式来测试。

代码:

#include
using namespace std;
string s;
int over(){
	char flag='0';
	for(int i=0;i<=2;i++){
		if(s[i*3]==s[i*3+1]&&s[i*3]==s[i*3+2]&&s[i*3]!='0') flag=s[i*3];
		if(s[i]==s[i+3]&&s[i]==s[i+6]&&s[i]!='0') flag=s[i];
	}
	if((s[0]==s[4]&&s[0]==s[8])||(s[2]==s[4]&&s[2]==s[6])){
		if(s[4]!='0') flag=s[4];
	}
	return flag-'0';
}
int score(){
	int ans=1;
	for(auto e:s) if(e=='0') ans++;
	return ans;//统计分数 
}
int dfs(bool Alice){
	int flag=over();
	if(flag==1) return score();
	else if(flag==2) return -1*score();
	int ans=-1;
	bool is_first=true;
	for(int i=0;i<s.length();i++){
		if(s[i]=='0'){
			s[i]=Alice?'1':'2';
			if(is_first) ans=dfs(!Alice);
			else ans=Alice?max(ans,dfs(false)):min(ans,dfs(true));
			s[i]='0';
			is_first=false;
		}
	}
	return ans;//如果放满了,返回-1 
}
int main(){
	int t;
	cin>>t;
//	getchar();
	while(t--){
		s="";		
//		for(int i=0;i<9;i++) s+=getchar(),getchar();
		for(int i=0;i<9;i++){
			int num;
			cin>>num;
			s+=to_string(num);
		}
		int sc=dfs(true);
		if(~sc) cout<<sc<<'\n';
		else cout<<0<<'\n';
	}
	return 0;
}

你可能感兴趣的:(CCF,CSP,#,数学)