• 洛谷2148(SDOI2009) E&D


    题目:https://www.luogu.org/problemnew/show/P2148

    SG函数+找规律。

    普通地用SG函数做。

    每两堆是一个独立问题。因为虽然有可能一个人在同一组里连续操作2次,但操作一次一定会把一个必败状态改为必胜状态,不会需要连续操作两次。

    关键是怎么快速求SG函数。

    打表找规律:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int sg[25][25];
    void dfs(int x,int y)
    {
        if(sg[x][y]!=-1)return;
        int sum=0;
        for(int i=1;i<x;i++)
        {
            dfs(i,x-i);
            sum|=(1<<sg[i][x-i]);
        }
        for(int i=1;i<y;i++)
        {
            dfs(i,y-i);
            sum|=(1<<sg[i][y-i]);
        }
        for(int i=0;i<=20;i++)
            if((sum&(1<<i))==0)
            {
                sg[x][y]=i;sg[y][x]=i;
                return;
            }
    }
    int main()
    {
        memset(sg,-1,sizeof sg);
        sg[1][1]=0;
        for(int i=1;i<=20;i++)
        {
            for(int j=1;j<=20;j++)
            {
                dfs(i,j);
                printf("%3d",sg[i][j]);
            }
            printf("
    ");
        }
        return 0;
    }
    View Code

    然后发现 i 和 j 的规律:

      SG=1:i % 2 ==1 && j % 2 ==1;

      SG=2:i % 4 == 1,2 && j % 4 == 1,2;

      SG=3:i % 8 == 1,2,3,4 && j % 8 == 1,2,3,4;

      ……

    所以有了那个log的算法。

    仔细一看,那个就是求 i 和 j 的第一个公共0在第几位,所以又有了O(1)的式子。

    但是那个O(1)的式子有一个点过不去,是把NO输出成YES,不知何故。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const ll N=2e4+5;
    ll T,n,a[2],sum;
    ll sg(ll a,ll b)
    {
        for(ll i=0,tmp=2;;i++,tmp<<=1)
            if((a-1)%tmp<(tmp>>1)&&(b-1)%tmp<(tmp>>1))
                return i;
    //    ll k=((a-1)|(b-1));
    //    k=((k+1)&(-k-1));
    //    return k-1;
    }
    int main()
    {
        scanf("%lld",&T);
        while(T--)
        {
            scanf("%lld",&n);sum=0;
            for(ll i=1;i<=n;i++)
            {
                scanf("%lld",&a[i&1]);
                if(!(i&1))sum^=sg(a[0],a[1]);
            }
            if(sum)printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    轮廓 | outline (Basic User Interface)
    转换 | CSS Transitions (Animations & Transitions)
    越线 | line-break (Text)
    贴士和技巧 | CSS Animations: Tips (Animations & Transitions)
    负 | @counter-style.negative (Counter Styles)
    调整 | resize (Basic User Interface)
    再见乱码:5分钟读懂MySQL字符集设置
    git
    Python 内存&函数调用关系图
    Python 笔记
  • 原文地址:https://www.cnblogs.com/Narh/p/9085607.html
Copyright © 2020-2023  润新知