首页 > 其他 > 详细

TYVJ 2049 魔法珠 sg函数

时间:2015-07-22 23:03:38      阅读:398      评论:0      收藏:0      [点我收藏+]

题意:链接

方法:sg函数

解析:

tyvj的题大部分都没题解啊- - 不过这样貌似会更好?感觉做这的题都需要自己动脑啊- - 虽然嘴上说着好烦然而心里觉得好评?

回归正题

设sg[x]表示数x的sg值,这好像是废话

然后对于读入的a[i],将所有的a[i]的sg值异或起来如果不是零则先手赢反之后手

维护的时候有个坑。

每次求约数的时候,数组要在sg里开,因为如果递归下去的话,全局变量的话会被更改,会被坑死。

然后就是怎么维护了

对于x,先求约数

之后枚举哪个数不取,将其他的异或(或者先都异或起来的和去跟每个异或会更快)

然后就AC了

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 110
using namespace std;
int n,cnt;
int num[N];
int sg[1010];
int b[1100];
void get(int x)
{
    cnt=1,b[cnt]=1;
    for(int i=2;i*i<=x;i++)
    {
        if(x%i==0)
        {
            if(i*i==x)b[++cnt]=i;
            else b[++cnt]=i,b[++cnt]=x/i;
        }
    }
}
int ssgg(int x)
{
    if(sg[x]!=-1)return sg[x];
    int v[1010];memset(v,0,sizeof(v));
    get(x);
    int tot=cnt,cal[110];
    for(int i=1;i<=cnt;i++)cal[i]=b[i];
    for(int i=1;i<=tot;i++)
    {
        int ans=0;
        for(int j=1;j<=tot;j++)
        {
            if(i==j)continue;
            ans^=ssgg(cal[j]);
        }
        v[ans]=1;
    }
    for(int i=0;;i++)if(!v[i])return sg[x]=i;
}
int main()
{

    while(~scanf("%d",&n))
    {
        memset(sg,-1,sizeof(sg));sg[1]=0;
        for(int i=1;i<=n;i++)scanf("%d",&num[i]);
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            ans^=ssgg(num[i]);
        }
        if(ans)printf("freda\n");
        else printf("rainbow\n");
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

TYVJ 2049 魔法珠 sg函数

原文:http://blog.csdn.net/wzq_qwq/article/details/47009209

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!