UVA 11859 Division Game (Nim博弈)

来源:互联网 发布:同花顺炒股软件 编辑:程序博客网 时间:2024/06/08 15:34

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32746

题意:有一个n*m(1<=n,m<=50)矩阵,每个元素均为2~10000之间的正整数,两个游戏者轮流操作。每次可以选一行中的1个或者大于1的整数,把他们中的每个数都变成它的某个真因子,比如12可以边长1,2,3,4或者6,不能操作的输。

分析:考虑每个数包含的素因子个数(比如12=2*2*3包含3个素因子),则让一个数“变成它的素因子”等价于拿掉它的一个或者多个素因子。这样每一行对应一个正整数x(x表示可以拿的素因子总个数),可以拿某一行的任意多个因子。这就转化成基本的Nim博弈了。

代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn = 103;int prime[maxn],nprime,cnt[maxn*maxn];bool isprime[maxn];void doprime(){nprime=0;fill(isprime+2,isprime+maxn,true);for(int i=2;i<maxn;i++)if(isprime[i]){prime[nprime++]=i;for(int j=2*i;j<maxn;j+=i)isprime[j]=false;}}void work(){doprime();memset(cnt,0,sizeof(cnt));for(int i=2;i<=10000;i++){int temp=i;for(int j=0;j<nprime;j++){if(temp%prime[j]==0){cnt[i]=cnt[temp/prime[j]]+1;temp=1;break;}}if(temp>1)cnt[i]=1;}}int main(){work();int ncase,n,m,i,j,ans,x;scanf("%d",&ncase);for(int T=1;T<=ncase;T++){scanf("%d%d",&n,&m);ans=0;for(i=1;i<=n;i++){int cal=0;for(j=1;j<=m;j++){scanf("%d",&x);cal+=cnt[x];}ans^=cal;}printf("Case #%d: %s\n",T,(ans?"YES":"NO"));}return 0;}


0 0
原创粉丝点击