蓝桥杯——灭鼠先锋

  • 博弈论
    本体运用到了基础博弈论的相关知识点,博弈论的本质是让自己处于必胜状态,他人处于必输状态,找到必输状态是核心
  • 博弈论两条状态转换公式
    1. 当前处于必输状态 ⇔ 下一步总能进入必胜状态 2. 存在一种策略 , 使得下一步进入必输状态 ⇒ 当前处于必胜状态 1.当前处于必输状态\Leftrightarrow 下一步总能进入必胜状态 \\ 2.存在一种策略,使得下一步进入必输状态\Rightarrow 当前处于必胜状态 1.当前处于必输状态下一步总能进入必胜状态2.存在一种策略,使得下一步进入必输状态当前处于必胜状态
  • 算法模板
#include<iostream>
#include<bits/stdc++.h>
#include <queue>
#include <algorithm> 
using namespace std;
//博弈论,让自己处于必胜,让对手处于必输
//处于必输状态当且仅当下一步无论怎么走都会导致必胜
//当下一步存在到达必输状态的走法,当前状态为必胜状态
//由于每个人都按照最优策略玩游戏所以只有必胜和必输两种可能,本游戏无随机性 
//初始化为图 
vector<vector<int>>	m(3,vector<int>(5,0));
//记录每个位置的标号
vector<vector<int>>	num(3,vector<int>(5,0));
const int N=1<<8;
//dp[i]表示状态i是否为必胜 
map<int,bool> dp;
//判断当前状态是否只有1个0,如果只剩下一个0,那么一定是必败状态 
bool check(int x){
    
    
	int num=0;
	int i=0;
	while(i<8){
    
    
		if(x%2==0)	num++;
		x=(x>>1);
		i++;
	}
	if(num==1)	return true;
	else		return false;
}
//判断是否为必胜状态 
bool dfs(int x){
    
    
	//轮到你时已经填满了,那么你就赢了 
	if(x==N-1)	return true; 
	//轮到你时还剩1个没填,那你必输 
	if(check(x))	return false;
	if(dp.find(x)!=dp.end())	return dp[x];
	bool flag=true;
	//先考虑当前状态下填2个
	for(int i=1;i<=2;i++){
    
    
		for(int j=1;j<=3;j++){
    
    
			if(m[i][j]==1||m[i][j+1]==1)	continue;
			m[i][j]=m[i][j+1]=1;
			x=x+(1<<num[i][j])+(1<<num[i][j+1]);
			dp.emplace(x,dfs(x));
			flag=dp[x];
			//回溯
			x=x-(1<<num[i][j])-(1<<num[i][j+1]);
			m[i][j]=m[i][j+1]=0;
			//如果能进入必输状态表明当前状态是必胜状态 
			if(flag==false)	return true; 
		}
	}

	//先考虑当前状态下填1个
	for(int i=1;i<=2;i++){
    
    
		for(int j=1;j<=4;j++){
    
    
			if(m[i][j]==1)	continue;

			m[i][j]=1;
			x=x+(1<<num[i][j]);
			dp.emplace(x,dfs(x));
			flag=dp[x];
			//回溯
			x=x-(1<<num[i][j]);
			m[i][j]=0;
			//如果能进入必输状态表明为必胜 
			if(flag==false)	return true; 
		}
	}
	return false;
}
int main(){
    
    
	//初始化坐标
	int countNum=0;
	for(int i=1;i<=2;i++){
    
    
		for(int j=1;j<=4;j++){
    
    
			num[i][j]=countNum;
			countNum++;
		}
	}
	bool res[4]; 
	//情况1
	m[1][1]=1;
	dp.emplace(1,dfs(1));
	res[0]=dp[1];
	m[1][1]=0;
	
	//情况2
	 m[1][1]=m[1][2]=1;
	 dp.emplace(3,dfs(3));
	 res[1]=dp[3];
	 m[1][1]=m[1][2];
	 
	 //情况3
	 m[1][2]=1;
	 dp.emplace(2,dfs(2));
	 res[2]=dp[2];
	 m[1][2]=0;
	 
	 //情况4
	 m[1][2]=m[1][3]=1;
	 dp.emplace(6,dfs(6));
	 res[3]=dp[6];
	 m[1][2]=m[1][3]=0;
	 for(int i=0;i<=3;i++){
    
    
	 	if(res[i]==false)	cout<<"V";
	 	else				cout<<"L";
	 }
	return 0;	
}

猜你喜欢

转载自blog.csdn.net/qq_33880925/article/details/129492595