题目链接:https://cn.vjudge.net/problem/HackerRank-stone-division
题目大意:给你n,m,然后是m个数。每一次你可以选择一个a[i],如果能被n整除,然后n就被分成了a[i]堆,每一堆有n/a[i]个。问你谁先无法分。
具体思路:对于当前的a[i],如果是偶数的话,那么只要第二个人怎么做,第一个人模仿就行了,这个时候是必胜态。
如果是奇数的话,判断当前单独一堆里面有多少个,然后判断一下这个n是不是必胜的,如果不是,那么先手赢,否则后手赢。
谢谢lxw的讲解
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const int maxn = 2e5+100; 5 ll n,m; 6 map<ll,bool>sg; 7 ll a[maxn]; 8 bool dfs(ll t) 9 { 10 if(sg.count(t)) 11 return sg[t]; 12 for(ll i=1; i<=m; i++) 13 { 14 if(t%a[i]) 15 continue; 16 if((a[i])%2==0) 17 { 18 sg[t]=1; 19 return 1; 20 } 21 else 22 { 23 if(!dfs(t/a[i])) 24 { 25 sg[t]=1; 26 return 1; 27 } 28 } 29 } 30 sg[t]=0; 31 return 0; 32 } 33 int main() 34 { 35 scanf("%lld %lld",&n,&m); 36 for(ll i=1; i<=m; i++) 37 { 38 scanf("%lld",&a[i]); 39 } 40 if(dfs(n)) 41 printf("First "); 42 else 43 printf("Second "); 44 return 0; 45 }