ACdream群OJ 1131 Apple 博弈

本文探讨了一个涉及复杂数学操作的问题解决方案,通过博弈论的视角,深入解析了如何利用策略和算法来确定玩家在特定游戏状态下的最优行动。文章详细介绍了问题的核心概念、算法实现以及实际应用案例,旨在帮助读者理解并掌握解决问题的关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:整理为,现在有两个数字n和m,两人每轮可以使得n++或者m++(有且必须选其一),第一个让n^m>=A的人为输。问第一个人是必输、必赢或平局。

思路:先用的sg求,发现平局没法表示。最后直接用0表示必输点、1表示必赢点、2表示平局。

问题的关键在于终止条件的判断。显然当 n>=2 && m>=2时候 子状态是有限且很少的,可以暴力询问所有子状态。

当n==1时,m其实可以取无限大。但是,发现当 (n+1)^m>=A时候,子状态只有一个,而且,显然这种状态为平局。

当m==1时,n<=A,状态有限但是太多。但是当n^(m+1)>=A,子状态只有一个,可以直接通过A-n的奇偶性判断此点状态。

特别的,当一开始n^m>=A时候,是先手必败。

//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<cctype>
#include<string>
#include<algorithm>
#include<iostream>
#include<ctime>
#include<map>
#include<set>
using namespace std;
#define MP(x,y) make_pair((x),(y))
#define PB(x) push_back(x)
typedef long long LL;
//typedef unsigned __int64 ULL;
/* ****************** */
const int INF=100011122;
const double INFF=1e100;
const double eps=1e-8;
const LL mod=20120427;
const int NN=10;
const int MM=1000010;
/* ****************** */

map<pair<int,int>,int>Mmap;
int cnt;
LL A;
int sg[1000000];
//0:lose
//1:win
//2:ping
pair<int,int>temp;

// n^m >= A
bool fun(int n,int m)
{
    if(n==1)
    {
        if(1>=A)
            return true;
        return false;
    }
    LL x=1;
    while(m--)
    {
        x=x*n;
        if(x>=A)
            return true;
    }
    return false;
}

int solve(int n,int m)
{
    temp=MP(n,m);
    int id;
    if(Mmap.count(temp)==0)
    {
        id=++cnt;
        sg[id]=-1;
        Mmap[temp]=id;
    }
    else
        id=Mmap[temp];

    if(sg[id]!=-1)return sg[id];
    if(fun(n,m))
    {
        sg[id]=1;
        return sg[id];
    }
    if(n==1 && fun(n+1,m))
    {
        sg[id]=2;
        return sg[id];
    }
    if(m==1 && fun(n,m+1))
    {
        sg[id]=1-( (A-n)%2 );
        return sg[id];
    }
    int x1=solve(n+1,m);
    int x2=solve(n,m+1);
    if(x1==0 || x2==0)
        sg[id]=1;
    else
    {
        if(x1==1 && x2==1)
            sg[id]=0;
        else
            sg[id]=2;
    }
    return sg[id];
}

int main()
{
    int x,z;
    int n,m;
    while(scanf("%d%d%d",&n,&m,&z)!=EOF)
    {
        Mmap.clear();
        cnt=0;
        A=z;
        if(fun(n,m))
        {
            puts("lose");
            continue;
        }
        x=solve(n,m);
      //  printf("cnt==%d\n",cnt);
        if(x==0)
            puts("lose");
        else if(x==1)
            puts("win");
        else
            puts("draw");
    }
    return 0;
}


### 关于东方博弈 OJ 1817 题目解决方案 针对东方博弈平台上编号为1817的题目,虽然具体题干未在此提及,但从涉及的内容推测该题目可能属于算法或编程挑战的一部分。基于此类平台的一般特性以及提供的参考资料[^1],这类题目通常旨在考察参赛者的逻辑思维能力和编程技巧。 #### 可能的主题领域 考虑到所给定的其他引用材料主要集中在算法设计、特别是有关博弈论的应用方面[^2],可以合理推断OJ 1817也可能围绕着相似的概念展开。例如: - **动态规划** - **贪心算法** - **图论中的路径优化** #### 推测性的解决框架 假设这是一个典型的博弈问题,那么解决问题的一个常见途径就是通过递归来模拟不同玩家之间的交互过程,并利用记忆化技术来提高效率。下面给出一段伪代码作为概念验证: ```python def solve_game(state): # Base case: check if current state is a losing position if is_losing_state(state): return False # Try all possible moves from the current state for next_state in generate_all_possible_moves(state): # If there exists any move leading to opponent's loss, this is winning strategy if not solve_game(next_state): return True # No available move leads to win; hence it’s a losing situation here. return False ``` 这段代码体现了如何评估某个特定状态下是否存在胜利的可能性——即能否找到至少一条通向对方失败局面的道路。 #### 实际编码建议 当实际编写程序时,应当注意输入数据结构的设计,确保能够高效处理各种边界情况。此外,由于许多在线评测系统会对运行时间和内存消耗有严格限制,因此还需要考虑性能优化措施,比如剪枝不必要的分支或是采用迭代加深等高级搜索策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值