蓝桥杯备赛---------灭鼠先锋

一、题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

灭鼠先锋是一个老少咸宜的棋盘小游戏,由两人参与,轮流操作。

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

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

XOOO XXOO OXOO OXXO
OOOO OOOO OOOO OOOO

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

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

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

二、解题思路

只能转移到必胜态,为必败态;

可以转移到必败态,为必胜态。

初始状态下,小蓝如果下完第一步,此时为必败态,那么说明小蓝赢了,如果此时为必胜态,那么说明小蓝输了。

三、代码实现

 

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <unordered_map>

using namespace std;

unordered_map<string, bool> st;

const int n = 8;

bool check(string str)
{
  int cnt = 0;
  for (auto c : str )
    cnt += c == 'O';
  return cnt == 1;
}

bool dfs(string str)
{
  if(st.count(str))
  {
    return st[str];
  }
  if(check(str))
  {
    st[str] = false;
    return false;
  }
  for (int i = 0; i < n; ++ i )
  {
    if(str[i] == 'X' )
      continue;
    string t = str;
    t[i] = 'X';
    if(!dfs(t))
    {
      st[str] = true;
      return true;
    }
  }
  for (int i = 0; i < 2; ++ i )
  {
    for(int j = 0; j < 3; ++ j )
    {
      int k = 4 * i + j;
      if(str[k] == 'X' || str[k + 1] == 'X')
        continue;
      string t = str;
      t[k] = t[k + 1] = 'X';
      if(!dfs(t))
      {
        st[str] = true;
        return true;
      }
    }
  }
  st[str] = false;
  return false;
}

int main()
{
  string be[] = {"XOOOOOOO", "XXOOOOOO", "OXOOOOOO", "OXXOOOOO"};
  for (auto str : be )
    cout << (dfs(str) ? 'L' : 'V');
  cout << endl;
  return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值