X-man

导航

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

 

 

posted on 2013-10-08 18:27  雨钝风轻  阅读(337)  评论(0编辑  收藏  举报