Play With Power(全网最详细的题解)

Play With Power

Masha和Stas正在玩一个游戏。在游戏的开始,给出一个定值N,同时有两个正整数A和B,初始时满足A^B≤N。
Masha先手。每一回合,玩家要将A和B的其中一个数加上1,但不能令到A^B>N,否则该玩家输。现在,Masha想知道,假如两人都使用最优策略,对于一个特定的N,不同的A、B的初始值谁将获胜呢?

这道题看上去是博弈论,但是仔细看会发现是DP或是记忆化搜索(心态爆炸)

用judge(a,b)来表示当a,b到了这种情况后的胜负,但是是你在接手这个局面后的胜负,就是说如果当 a b > n a^b>n ab>n时,这种情况是输了,但是对于这在接手的你来说,是赢的,
我们用0来表示输了,2表示赢了,1表示平局,
存一个g[a][b]来表示 a b a^b ab是否超过n,如果超过了,说明这个情况你是赢了(再理解理解),
然后,当judge(a+1,b)和judge(a,b+1)都是赢的话,对于你来说就是输了,因为你没有方法让这个情况的后面两个其中一个让你自己赢,
但如果这两个有一个是必败的话,那么现在对于你来说就是必胜的,
其他情况都是平局,即1

然后特判,当b=1的时候且a比较大,就是n-a的值,是奇数就先手赢,偶数后手赢。
以及不要忘了 long long 和快速幂,快速幂中为了防止它爆了,要在快速幂中加特盘嘤嘤嘤

#include<bits/stdc++.h>
using namespace std;
long long n;
int g[100010][40];
long long kai(long long a,long long b)
{
	long long ans=1;
	if (a>n) return -1;
    while(b>0) 
	{
        if(b&1) ans*=a;
        a*=a;
        b>>=1;
        if (ans>n) return -1; 
    }
    return ans;
}
long long judge(long long a,long long b)
{
  if (b>30) return 1;
  if (g[a][b]==0) g[a][b]=kai(a,b);
  if (g[a][b]==-1) return 2;
  long long x=judge(a+1,b),y=judge(a,b+1);
  if (x==2&&y==2) return 0;
  if (x==0||y==0) return 2;
  return 1; 
}
int main()
{
	freopen("play.in","r",stdin);
	freopen("play.out","w",stdout);
	scanf("%lld",&n); 
	int t;
	scanf("%d",&t);
	long long ss=sqrt(n);
	while (t--)
	{
	  long long a,b;
	  scanf("%lld%lld",&a,&b);
	  int p;
	  if(a>ss) p=b==1?(n-a&1?2:0):0;
	  else p=judge(a,b);
	  if (p==2) printf("Masha\n"); 
	  if (p==1) printf("Missing\n");
      if (p==0) printf("Stas\n");
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值