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\n");

        else printf("Dave\n");

    }

    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("\n");//if(i==52)printf("\n");

    }*/

    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\n");

        else printf("Dave\n");

    }

    return 0;

}
View Code

 

 

你可能感兴趣的:(HDU)