D - Stone Division HackerRank - stone-division (博弈+搜索)

时间:2019-03-15
本文章向大家介绍D - Stone Division HackerRank - stone-division (博弈+搜索),主要包括D - Stone Division HackerRank - stone-division (博弈+搜索)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目链接: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\n");
42     else
43         printf("Second\n");
44     return 0;
45 }