题意:有N个数,Alice 和 Bob 轮流对这些数进行操作,若一个数 n=a*b且a>1,b>1,可以将该数变成 a 和 b 两个数;

或者可以减少为a或b,Alice先,问谁能赢

思路:首先单看对每个数进行除法的操作,我们可以知道其实是在除以每个数的素因子或素因子之间的积

比如 70=2*5*7 我们可以变成 10(2*5)或 14(2*7) 或 35(5*7)或 2 或 5 或 7 或 1 这七种状态

当我们把他们(2,5,7)当作3个石子也就是一堆时,然而实际上我们是将这堆石子进行nim游戏

我拿走一个石子 =》 10(2*5) 我拿走了石子7

14 (2*7) 我拿走了石子5

35 (5*7) 我拿走了石子2

我拿走两个石子 =》 2    我拿走了石子5 和 石子7

5    我拿走了石子2 和 石子7

7    我拿走了石子2 和 石子5

我拿走三个石子 =》 1     我拿走了石子2 和 石子5 和 石子7

接下来我们分析把一个数n=a*b变成 a 和 b ,其实这里上面的思想很像,把它当作石子的分堆

我可以分成             第一种 10(2*5) 和 7

第二种 14(2*7) 和 5

第三种 35(5*7) 和 2

综上所诉,根据正整数唯一分解定理,任何一个正整数x必然有x=(p1^r1)*(p2^r2)*......*(pn^rn)

定义sum=r1+r2+...+rn,这个sum的值就是这堆石子的总数,那么sg=sg[sum1]^sg[susm2]^....

问题又来了? 这个sum我们应该如何求呢?

我们可以通过素数筛得到每一个数的最小质因子,我们得到一个类似于递推的公式

一个正整数的质因子的个数=(这个正整数 / 这个数的最小质因子 所得数) 的质因子个数 + 1(也就是加上这是最小质因子的数量 1)

接下来代码实现就可以了

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 5000000
using namespace std; int prime[maxn+],k=,samll[maxn],sum[maxn];
bool visit[maxn+];
int sg[]; void get_prime()
{
memset(visit,false,sizeof(visit));
memset(samll,,sizeof(samll));
memset(sum,,sizeof(sum));
for(int i=;i<=maxn;i++)
{
if(visit[i]==false)
{
prime[k++]=i;
for(int j=i+i;j<=maxn;j+=i)
{
visit[j]=true;
if(samll[j]==) samll[j]=i;
}
samll[i]=i;
}
}
for(int i=;i<=maxn;i++)
sum[i]=sum[i/samll[i]]+;
} int get(int n)
{
if(sg[n]!=-) return sg[n];
bool vis[];
memset(vis,false,sizeof(vis));
for(int i=;i<=n;i++)
vis[get(n-i)]=true;
for(int i=;i<=n/;i++)
vis[get(i)^get(n-i)]=true;
int k;
for(int i=;i<;i++)
{
if(vis[i]==false)
{
return sg[n]=i;
}
}
} int main()
{
get_prime();
memset(sg,-,sizeof(sg));
sg[]=;
sg[]=;
for(int i=;i<=;i++)
{
get(i);
}
int n;
while(cin>>n)
{
int ans=;
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
ans=ans^sg[sum[x]];
}
if(ans)
cout<<"Alice"<<endl;
else
cout<<"Bob"<<endl;
}
return ;
}

最新文章

  1. BZOJ 3236: [Ahoi2013]作业
  2. oracle---plsql---示例laobai
  3. linux通过端口号查找程序执行路径
  4. 1106 c程序的推导过程
  5. [作业向]tinyhttp web服务器设计及完整代码
  6. MySQL数据库数据类型之集合类型SET测试总结
  7. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程08:虚拟键盘实现》--本系列完结
  8. Java Hashtable类
  9. .NET平台下几种SOCKET模型的简要性能供参考
  10. DOM对象控制HTML无素——详解3
  11. android开发步步为营之68:Facebook原生广告接入总结
  12. Java_String_01_由转义字符串得到其原本字符串
  13. SpriteBuilder中如何给精灵添加帧动画
  14. jmeter如何录制App及Web应用
  15. 实现数据结构与算法需要掌握的C语言
  16. windows docker常用命令
  17. Python中property的使用
  18. n的阶乘-编程2.md
  19. javascript中this的妙用
  20. 将C语言宏定义数值转换成字符串!

热门文章

  1. Gulp实现css、js、图片的压缩以及css、js文件的MD5命名
  2. 使用EntityFramework中DbSet.Set(Type entityType)方法碰到的问题
  3. SVN的具体使用方法介绍(安装以及操作)
  4. angular2入门,就这一篇就够了
  5. How to build mscorlib.dll with visual studio
  6. 2017年的golang、python、php、c++、c、java、Nodejs性能对比(golang python php c++ java Nodejs Performance)
  7. Eclipse的Spring IDE插件的安装和使用
  8. JavaScript实现评论点赞功能
  9. 九度OJ题目1076:N的阶乘 (java)运用BigInteger的例子。
  10. JavaWeb之JSON