zoukankan      html  css  js  c++  java
  • hdu 4664 Triangulation(题意已在讨论版中说明)

    题意:

      给定n个平面(平面之间相互独立),每个平面上有一些点,并且构成凸集,C和D轮流选一个平面连接两个点画线段,并保证线段之间除了端点之外没有其它交点,当平面上出现一个完整的三角形之后此平面就不能继续画线。最早无法画线的人输。输出赢的人。

    解法:

      因为n个平面是独立的,所以sg函数满足异或的关系。对于每一个平面,求sg值。对于n个点,连上一条线可以分成 i 和 n-2-i 两个独立的部分。所以该点的子状态为sg[i]^sg[n-i-2](0<=i<=n-2)。然后可以计算该点的sg值。打表发现n>68之后会出现长度为34的循环,所以打个34×3的表就可以了。sg函数是个好东西啊!

    递归搜索求SG函数:

    #include<stdio.h>
    #include<string.h>
    #define N 1000
    int sg[N];
    int GetSG(int k)
    {
        if(sg[k]!=-1)return sg[k];
        bool mex[N]={0};
        for(int i = 0; i <= k-2; i++)
        {
            sg[i] = GetSG(i);
            sg[k-i-2] = GetSG(k-i-2);
            mex[sg[i]^sg[k-i-2]]=1;
        }
        int i=0;
        while(mex[i])i++;
        return sg[k]=i;
    }
    int main()
    {
        int i,j;
        int t,n,x,ans;
        memset(sg,-1,sizeof(sg));
        GetSG(90);
        scanf("%d",&t);
        while(t--)
        {
            ans=0;
            scanf("%d",&n);
            for(i=0;i<n;i++)
            {
                scanf("%d",&x);
                if(x>86)ans^=sg[(x-53)%34+53];
                else ans^=sg[x];
            }
            if(ans)printf("Carol
    ");
            else printf("Dave
    ");
        }
        return 0;
    }
    View Code

    循环求SG

    #include<stdio.h>
    #include<string.h>
    #define N 1000
    int sg[N];
    int hash[N];
    void GetSG(int n)
    {
        int i,j,k;
        sg[0]=0;
        sg[1]=0;
        for(i=2;i<=n;i++)
        {
            memset(hash,0,sizeof(hash));
            for(j=0;i>=2+j&&j<=i/2;j++)
            hash[sg[j]^sg[i-2-j]]=1;
            for(j=0;j<=n;j++)
            {
                if(!hash[j])
                {
                    sg[i]=j;
                    break;
                }
            }
        }
    }
    int main()
    {
        int i,j;
        int t,n,x,ans;
        GetSG(200);//改成GetSG(90);就WA了,奇葩错误啊
        /*
        GetSG(200);
        for(i=0;i<=200;i++)
        {
            printf("%d ",sg[i]);
            if(i>=52&&(i-52)%34==0)printf("
    ");//if(i==52)printf("
    ");
        }*/
        scanf("%d",&t);
        while(t--)
        {
            ans=0;
            scanf("%d",&n);
            for(i=0;i<n;i++)
            {
                scanf("%d",&x);
                if(x>86)ans^=sg[(x-53)%34+53];
                else ans^=sg[x];
                /*if(x<86) ans^=sg[x];
                else ans^=sg[x%34+68];*/
    
            }
            if(ans)printf("Carol
    ");
            else printf("Dave
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    脏读,不可重复读,幻读区别和避免
    CSRF和XSS区别和预防
    mysql刷题(不定时更新)
    (12)arp命令(每周一个linux命令)
    (11)nc命令(每周一个linux命令)
    Codeforces Round #653 (Div. 3)(A, B, C, D, E1详解)
    Gauss高斯消元——模板
    F:Maximum White Subtree(dp)
    E:Three Blocks Palindrome(hard and easy)(树状数组 ? 前缀和?)
    E:K-periodic Garland(DP)
  • 原文地址:https://www.cnblogs.com/XDJjy/p/3357628.html
Copyright © 2011-2022 走看看