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先手赢,否则后手赢。

原文地址:https://www.cnblogs.com/lfri/p/11624198.html