zoukankan      html  css  js  c++  java
  • Zoj 3529 A Game Between Alice and Bob 数论+博弈Nim 快速求数中有多少个素数因子

    本题涉及博弈论中的Nim游戏博弈。

    Nim游戏博弈详解链接:

    http://www.cnblogs.com/exponent/articles/2141477.html

    本题解题报告详解链接:

    http://blog.csdn.net/woshi250hua/article/details/7824609

    我的代码,写的较挫,4000多ms,压着时间过,时间限制是5s.我预处理了所有1-5*10^6的数的素因子个数,用的是dp

    的思想,先预处理1-5*10^6的数的最小素因子,存在a数组中,然后dp[i] = dp[i/a[i] ]+1;

    我觉得我代码最挫的地方是在求最小素因子时费时太多。。。。

     1 #include <cstdio>
     2 #define N 5000005
     3 #define INF 0x7fffffff
     4 int p[N];//每个数有多少个素数因子
     5 int a[N];//每个数最小的素数因子
     6 int prime[700];//存素数表
     7 void init()
     8 {
     9     //打素数表,求出1-5005以内的素数和每个数的最小质因子
    10     for(int i=0; i<700; ++i)
    11         prime[i] = INF;
    12     prime[0] = 2;
    13     int num = 0;
    14     for(int i=3; i<5005; ++i)
    15     {
    16         int x = 0;
    17         while(i%prime[x] && prime[x] <= i)   ++x;
    18         if( !(i%prime[x]) )
    19             a[i] = prime[x];
    20         else
    21         {
    22             prime[++num] = i;
    23             a[i] = i;
    24         }
    25     }
    26     a[2] =2;
    27     for(int i=5005; i< N; ++i)
    28     {
    29         int x = 0;
    30         while(i%prime[x] && prime[x] <= i)   ++x;
    31         if( !(i%prime[x]) )
    32             a[i] = prime[x];
    33         else
    34             a[i] = i;
    35     }
    36     p[2] = 1;
    37     for(int i=3; i <N; ++i)
    38         p[i] = p[i/a[i]] + 1;
    39 }
    40 int main()
    41 {
    42 //    freopen("in.cpp","r",stdin);
    43     init();
    44     int n;
    45     int b[100005];
    46     int t=0;
    47     while(scanf("%d",&n) != EOF)
    48     {
    49         int ans ;
    50         for(int i=0; i<n; ++i)
    51         {
    52             scanf("%d",&b[i]);
    53             if(i)
    54                 ans ^= p[b[i]];
    55             else
    56                 ans = p[b[i]];
    57         }
    58         printf("Test #%d: ",++t);
    59         if(ans)
    60         {
    61             int index;
    62             for(int i=0; i<n; ++i)
    63                 if( (p[b[i]]^ans) < p[b[i]] )
    64                 {
    65                     index = i+1;
    66                     break;
    67                 }
    68             printf("Alice %d
    ",index);
    69         }
    70         else printf("Bob
    ");
    71     }
    72     return 0;
    73 }
    View Code

     这是改进后的代码,用线性筛法在打素数表的同时求出最小素因子····

    初始化时每个数的最小素因子就是本身。

     1 #include <cstdio>
     2 #define N 5000005
     3 #define INF 0x7fffffff
     4 int p[N];//每个数有多少个素数因子
     5 bool v[N]; //是否为素数
     6 int a[N];//每个数最小的素数因子
     7 int prime[N/10];//素数表
     8 //用打素数表的筛法求每个数的最小质因子
     9 void init()
    10 {
    11     for(int i=2; i<N; ++i)
    12         a[i] = i;
    13     int num=-1;
    14     for(int i=2; i<N; ++i)
    15     {
    16         if(!v[i]) prime[++num] = i;
    17         for(int j=0; j<=num && i*prime[j] < N; ++j)
    18         {
    19             int t = i*prime[j];
    20             v[t] =1;
    21             if(a[t] > prime[j]) a[t] = prime[j];
    22             if(i%prime[j] == 0) break;
    23         }
    24     }
    25     p[2] = 1;
    26     for(int i=3; i <N; ++i)
    27         p[i] = p[i/a[i]] + 1;
    28 }
    29 
    30 int main()
    31 {
    32 //    freopen("in.cpp","r",stdin);
    33     init();
    34     int n;
    35     int b[100005];
    36     int t=0;
    37     while(scanf("%d",&n) != EOF)
    38     {
    39         int ans ;
    40         for(int i=0; i<n; ++i)
    41         {
    42             scanf("%d",&b[i]);
    43             if(i)
    44                 ans ^= p[b[i]];
    45             else
    46                 ans = p[b[i]];
    47         }
    48         printf("Test #%d: ",++t);
    49         if(ans)
    50         {
    51             int index;
    52             for(int i=0; i<n; ++i)
    53                 if( (p[b[i]]^ans) < p[b[i]] )
    54                 {
    55                     index = i+1;
    56                     break;
    57                 }
    58             printf("Alice %d
    ",index);
    59         }
    60         else printf("Bob
    ");
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    STM32F407 开发环境搭建 程序下载 个人笔记
    用bootstrap_table实现html 表格翻页
    STM32F407 正点原子 资料网址记录
    C51 动态数码管 个人笔记
    C51 继电器 个人笔记
    谷歌浏览器截长图
    C51 原创电子琴 (蜂鸣器/计时器/中断/矩阵按键)
    从零自学Hadoop(01):认识Hadoop
    Centos修改DNS重启或者重启network服务后丢失问题处理
    初次体验VS2015正式版,安装详细过程。
  • 原文地址:https://www.cnblogs.com/allh123/p/3234290.html
Copyright © 2011-2022 走看看