zoukankan      html  css  js  c++  java
  • 石子游戏【博弈论】

    题目大意:

    n堆石子,两人轮流取石子,每次可以将一堆全部拿走,也可以选择其中y个拿,但是要求y与这堆石子的总个数互质。求谁会胜利。


    思路:

    明显的博弈论之SG函数。
    我们可以发现,质数的SG值就等于上一个质数的SG值加一,而合数的SG值就是它的最小质因子的SG,所以,我们先预处理出所有质数(一遍 埃拉托斯特尼筛法 后顺便求出每个数的SG值),再遍读入遍异或,再判断是01即可。
    时间复杂度:O(tn2),但是很多时间达不到n2,平均只有O(tn)


    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    const int N=1000000;
    int t,n,sg[N+50],k,ans,x;
    
    void find_prime()  //筛质数
    {
        sg[1]=k=1;
        for (int i=2;i<=N;i++)
        {
            if (sg[i]) continue;  //不是质数
            sg[i]=++k; 
            for (int j=i;j<=N;j+=i)
             if (!sg[j]) sg[j]=k;  //if语句是必须的,因为合数的SG值是它最小值因子的SG值
        }
        return;
    }
    
    int main()
    {
        scanf("%d",&t);
        find_prime();
        while (t--)
        {
            scanf("%d",&n);
            ans=0;
            for (int i=1;i<=n;i++)  
            {
                scanf("%d",&x);
                ans^=sg[x];  //异或,不懂情科普博弈论普及知识
            }
            if (ans) printf("Alice\n");
             else printf("Bob\n");
        }
        return 0;
    }
  • 相关阅读:
    vue组件基本结构及各个生命周期
    vue项目目录结构详解
    http请求报文格式和响应报文格式
    H5中对history栈的操作
    原生js实现元素类名的判存、添加和移除
    Content-type解析
    IntelliJ Idea 常用快捷键列表
    深入ES6中的class类
    v-model和 .sync
    作用域插槽
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998872.html
Copyright © 2011-2022 走看看