weinan030416

导航

下棋判断必败必胜

每次下一个或者两个棋,你先开始下,空位n个,填满最后一个位置输

分析得到必胜必败状态

1败,2胜,3胜,4败,5胜,6胜,7败...

只剩4个空位的状态只能转移到3个空位或两个空位,此时对手必胜,所以自己必败,以此类推

#include<iostream>
using namespace std;

bool dfs(int n)
{
    if(n==1)    return false;
    if(n==2)    return true;
    if(n==3)    return true;
    if(dfs(n-1)&&dfs(n-2))//只能转移到对手的必胜态 
    return false;
    else
    return true;
}

int main()
{
    int n;
    cin>>n;
    if(dfs(n))
    cout<<"ok";
    else
    cout<<"no";
}

灭鼠先锋的棋盘有各种规格,本题中游戏在两行四列的棋盘上进行。游戏的规则为:两人轮流操作,每次可选择在棋盘的一个空位上放置一个棋子,或在同一行的连续两个空位上各放置一个棋子,放下棋子后使棋盘放满的一方输掉游戏。

小蓝和小乔一起玩游戏,小蓝先手,小乔后手。小蓝可以放置棋子的方法很多,通过旋转和翻转可以对应如下四种情况:

XOOO XXOO OXOO OXXO
OOOO OOOO OOOO OOOO

其中 O 表示棋盘上的一个方格为空,X 表示该方格已经放置了棋子。

请问,对于以上四种情况,如果小蓝和小乔都是按照对自己最优的策略来玩游戏,小蓝是否能获胜。如果获胜,请用 V 表示,否则用 L 表示。请将四种情况的胜负结果按顺序连接在一起提交。

#include<bits/stdc++.h>
using namespace std;
///判断是否仅存在一个空格
bool check(string s)
{
    int tot = 0;
    for(int x=0;x<s.size();x++)if(s[x] == 'O')
        tot++;
    return tot == 1;
}
map<string, bool>SG;
bool dfs(string s)
{
    //状态s已经被计算
    if(SG.count(s))
        return SG[s];
    //状态s为递归出口
    if(check(s))
        return SG[s] = false;
    ///模拟放1个棋子
    for(int i = 0; i < s.size(); i++)if(s[i] == 'O')
    {
        string tmp = s;
        tmp[i] = 'X';
        if(dfs(tmp) == false)///可以到达必败态均为必胜态
            return SG[s] = true;
    }
    ///模拟放2个棋子
    for(int i = 0; i < s.size() - 1; i++)if(s[i] == 'O' && s[i + 1] == 'O' && i != 3)
    {
        string tmp = s;
        tmp[i] = tmp[i + 1] = 'X';
        if(dfs(tmp) == false)///可以到达必败态均为必胜态
            return SG[s] = true;
    }
    ///运行到此,说明只能转移到必胜态,此时为必败态
    return SG[s] = false;
}

int main()
{
    string s[] = {"XOOOOOOO", "XXOOOOOO", "OXOOOOOO", "OXXOOOOO"};
    for(int i = 0; i < 4; i++)
    {
        if(dfs(s[i]))cout<<"L";///此时为必胜态,说明后手面临的局面必胜,输出L
        else cout<<"V";
    }
    return 0;
}

 

#include<bits/stdc++.h>
using namespace std;
///判断是否仅存在一个空格
bool check(string s)
{
    int tot = 0;
    for(int x=0;x<s.size();x++)if(s[x] == 'O')
        tot++;
    return tot == 1;
}
map<string, bool>SG;
bool dfs(string s)
{
    //状态s已经被计算
    if(SG.count(s))
        return SG[s];
    //状态s为递归出口
    if(check(s))
        return SG[s] = false;
    ///模拟放1个棋子
    for(int i = 0; i < s.size(); i++)if(s[i] == 'O')
    {
        string tmp = s;
        tmp[i] = 'X';
        if(dfs(tmp) == false)///可以到达必败态均为必胜态
        {
            cout<<tmp<<"    "<<"L"<<endl;
            return SG[s] = true;
        }
            
    }
    ///模拟放2个棋子
    for(int i = 0; i < s.size() - 1; i++)if(s[i] == 'O' && s[i + 1] == 'O' && i != 3)
    {
        string tmp = s;
        tmp[i] = tmp[i + 1] = 'X';
        if(dfs(tmp) == false)///可以到达必败态均为必胜态
        {
            cout<<tmp<<"    "<<"L"<<endl;
            return SG[s] = true;
        }
            
    }
    ///运行到此,说明只能转移到必胜态,此时为必败态
    return SG[s] = false;
}

int main()
{
    string s[] = {"XXXXOOOO", "XXOOOOOO", "OXOOOOOO", "OXXOOOOO"};
    for(int i = 0; i < 4; i++)
    {
        if(dfs(s[i]))cout<<"    L    ";///此时为必胜态,说明后手面临的局面必胜,输出L
        else cout<<"    V    ";
    }
    cout<<endl;
//    for(map<string,bool>::iterator it=SG.begin();it!=SG.end();it++)
//    cout<<it->first<<" "<<it->second<<endl;
    return 0;
}

 

posted on 2023-02-08 21:42  楠030416  阅读(45)  评论(0编辑  收藏  举报