zoukankan      html  css  js  c++  java
  • 【hdu 1848】Fibonacci again and again

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 8194 Accepted Submission(s): 3410

    Problem Description
    任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:
    F(1)=1;
    F(2)=2;
    F(n)=F(n-1)+F(n-2)(n>=3);
    所以,1,2,3,5,8,13……就是菲波那契数列。
    在HDOJ上有不少相关的题目,比如1005 Fibonacci again就是曾经的浙江省赛题。
    今天,又一个关于Fibonacci的题目出现了,它是一个小游戏,定义如下:
    1、 这是一个二人游戏;
    2、 一共有3堆石子,数量分别是m, n, p个;
    3、 两人轮流走;
    4、 每走一步可以选择任意一堆石子,然后取走f个;
    5、 f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
    6、 最先取光所有石子的人为胜者;

    假设双方都使用最优策略,请判断先手的人会赢还是后手的人会赢。

    Input
    输入数据包含多个测试用例,每个测试用例占一行,包含3个整数m,n,p(1<=m,n,p<=1000)。
    m=n=p=0则表示输入结束。

    Output
    如果先手的人能赢,请输出“Fibo”,否则请输出“Nacci”,每个实例的输出占一行。

    Sample Input
    1 1 1
    1 4 1
    0 0 0

    Sample Output
    Fibo
    Nacci

    【题目链接】:http://acm.hdu.edu.cn/showproblem.php?pid=1848

    【题解】

    把3个堆分开算;
    分别搞出sg函数来;
    sg[x]=mex{sg[x-fib[1]],sg[x-fib[2]],….};
    mex{A}
    表示不在A这个集合里面的最小整数;
    这个组合博弈;可以加在一起;
    所以还是看异或值
    只不过换成了
    sg[n]^sg[m]^sg[p]
    如果为0;
    则先手输
    否则先手赢;

    假设游戏 Gi的SG函数是gi, i=1,…,n, 则
    G = G1 + … + Gn 的 SG函数是
    g(x1,…,xn) = g1(x1) ^g1(x2)…^gn(xn).


    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int MAXN = 1e3+10;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int m,n,p;
    int fib[20],sg[MAXN];
    bool flag[20];
    
    void get_sg()
    {
        sg[0] = 0;
        sg[1] = 1;
        rep1(i,2,1000)
        {
            memset(flag,false,sizeof flag);
            for (int j = 1;i-fib[j]>=0;j++)
                flag[sg[i-fib[j]]] = true;
            rep1(j,0,16)
                if (!flag[j])
                {
                    sg[i] = j;
                    break;
                }
        }
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        fib[1] = 1;fib[2] = 2;
        rep1(i,3,16)
            fib[i] = fib[i-1]+fib[i-2];
        get_sg();
        rei(m);rei(n);rei(p);
        while (m!=0 || n!=0 || p!=0)
        {
            if ((sg[m]^sg[n]^sg[p])==0)
                puts("Nacci");
            else
                puts("Fibo");
            rei(m);rei(n);rei(p);
        }
        return 0;
    }
  • 相关阅读:
    入门(一)---Java的发展史
    移除元素
    TCP的 “三次握手” 和“四次挥手”,到底是什么鬼?
    功能测试框架
    python学习笔记之--__new__方法和__init__方法
    HTTP协议状态码详解
    python学习笔记之--hasattr函数
    一文总结软件测试工程师面试前必背的面试题(持续更新中)
    MYSQL安装file /usr/share/mysql/charsets/README from install of MySQL-server-5.6.35-1.el6.x86_64 conflicts with file from package mariadb-libs-1:5.5.60-1.el7_5.x86_64报错
    centos7 安装salt起不来处理
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626748.html
Copyright © 2011-2022 走看看