[AtCoder Regular Contest 091 F] Strange Nim

10 篇文章 0 订阅
5 篇文章 0 订阅

题目描述:

有 N 堆石子
每堆石子有 数量 A 和 参数 K
两位选手每次选一堆石子进行取出,可以取 1-floor(A/k)(A为当前本堆石子数量,并不是常量)

题目分析:

WTF!!!
第一次做一点都不裸的Nim 博弈
首先,打表程序蛮好写的

int dfs(int x,int k)
{
    //printf("%d %d\n",x,k);
    if(~SG[x][k]) return SG[x][k];
    if(x==0) return 0;
    if(x<k) return 0;
    bool vis[10001];
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=x/k;i++)
    {
        if(~SG[x-i][k]) vis[SG[x-i][k]]=1;
        else vis[dfs(x-i,k)]=1;
    }
    for(int i=0;;i++)
    if(!vis[i])
    {
       SG[x][k]=i;
       //printf("x:%d k:%d SG[x][k]:%d x%%k:%d x/k:%d\n",x,k,i,x%k,x/k);
       return i;    
    }
}

然而 1<=A,K<=109 1 <= A , K <= 10 9
所以又到了喜闻乐见的找规律时间了.
找规律?
以下找规律转化内容均来着SD神犇rqy orz
SG[kx][k]=xSG[kx+b][k]=SG[(k1)x+(b1)][k] S G [ k ∗ x ] [ k ] = x 且 S G [ k ∗ x + b ] [ k ] = S G [ ( k − 1 ) ∗ x + ( b − 1 ) ] [ k ]
哇,这规律咋找的?
我们固定一个 K 然后输出一下 SG[1-n][K]
会发现如果我们搞出的SG排列,把K的倍数删去,一点变化都没有
比如k=2的时候数列是0 0 1 0 2 1 3 0 4 2 5 1 6 3…
偶数位显然是0 1 2 3 4 5 6…
把所有奇数位拿出来之后还是0 0 1 0 2 1 3 0 4 2 5 1 6 3
不得不说 rqy就是强
直接这么算会T
可以发现从kx+b到(k-1)x+(b-1)减去了(x+1)
不停地减去x+1直到k变小为止
一共要减ceil(b/(x+1))次,也就是(b+x)/(x+1)(下取整)次

题目链接:

AtCoder Regular Contest 091 F

Ac 代码:

#include <cstdio>
#include <iostream>
int SG(int a,int k)
{
    int x=a/k,b=a%k;
    if(!b) return x;
    int t=(b+x)/(x+1);
    return SG(a-t*(x+1),k);
}
int main()
{
    int n;
    scanf("%d",&n);
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        int a,k;
        scanf("%d%d",&a,&k);
        ans^=SG(a,k);
    }
    puts(ans?"Takahashi":"Aoki");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值