• A Funny Game——打表&&找规律


    题目

    n枚硬币排成一个圈。Alice和Bob轮流从中取一枚或两枚硬币。不过,取两枚时,所取的两枚硬币必须是连续的。硬币取走之后留下空格,相隔空格的硬币视为不连续。Alice开始先取,取走最后一枚硬币的获胜。当双方都采取最有策略时,谁会获胜?

    分析

    不管,先爆搜找规律。

    #include<bits/stdc++.h>
    using namespace std;
    
    
    typedef unsigned long long ll;
    const int maxn = 50;
    int a[maxn], n;
    map<ll, int>mp;
    
    bool check()
    {
        bool flag = true;
        for(int i = 0;i < n;i++)
            if(a[i] == 0)  flag = false;
        return flag;
    }
    
    ll state()
    {
        ll ret = 0;
        for(int i = 0;i < n;i++)  ret = ret *2 + a[i];
        return ret;
    }
    
    
    int dfs(int cnt)  //必胜返回1,平局返回2,必败返回-1
    {
        int& ret = mp[state()];
        if(ret)  return ret;
        if(check())  return ret=-1;
        if(cnt >= n)  return ret=2;
        bool flag = false;       //能否成平局
        for(int i = 0;i < n;i++)
        {
            if(a[i])  continue;
    
            a[i] = 1;
            int tmp = dfs(cnt+1);
            a[i] = 0;
            if(tmp == -1)  return ret=1;    //后面存在必败态,先手必胜
            if(tmp == 2)  flag = true;  //存在平局
    
            if(a[(i+1)%n] == 0)
            {
                a[i] = 1;
                a[(i+1)%n] = 1;
                int tmp = dfs(cnt+2);
                a[i] = 0;
                a[(i+1)%n] = 0;
                if(tmp == -1)  return ret=1;    //后面存在必败态,先手必胜
                if(tmp == 2)  flag = true;  //存在平局
            }
        }
        return ret=(flag ? 2 : -1);
    }
    
    int main()
    {
        for(n=1;;n++)
        {
            memset(a, 0, sizeof(a));
            mp.clear();
            printf("%d %d
    ", n, dfs(0));
        }
    }

     规律很明显,小于等于2先手赢,否则后手赢。

  • 相关阅读:
    canvas小球动画
    JS闭包
    视图&&事务&&索引&&触发器&&流程控制
    多表关系和查询
    表操作和mysql支持的数据类型
    models模型层进阶
    模型层之聚合查询&&分组查询&&查询&&Q查询&&事务&&查询优化
    models模型层环境配置和表查询
    模型层之orm介绍
    views视图层
  • 原文地址:https://www.cnblogs.com/lfri/p/11624198.html
Copyright © 2020-2023  润新知