可惜没如果=_=
时光的河入海流

题目链接在这里:G-Deleting Divisors_牛客竞赛博弈专题班组合游戏基本概念、对抗搜索、Bash游戏、Nim游戏习题 (nowcoder.com)

这道题一道比较明显的思路是使用sg函数,因为可以看到比较明显的一个状态推到另一个状态的过程。在考场上的话应该想到的是通过sg函数打表找规律来做。

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 const int MAX=100005;
 4 int n;
 5 int sg[MAX];
 6 int main(){
 7     int i,j;
 8     memset(sg,0,sizeof(sg));
 9     for (i=2;i<=1000;i++)
10         for (j=2;j*j<=i;j++)
11             if (i%j==0){
12                 if (sg[i-j]==0 || sg[i-i/j]==0)
13                     sg[i]=1;
14             }
15     for (i=1;i<=1000;i++)
16         cout<<i<<" : "<<sg[i]<<endl;
17     return 0;
18 }

 

 

下面是正解:

通过分解质因数然后观察可以看出这个和奇偶性是有关系的,我们就来考虑两种状态:

1. 如果当前数为一个奇数,那么它的所有因子一定是奇数,所以它减掉一个因子一定是一个偶数,即它的下一状态要么是已经寄了,要么是第二状态。

2. 如果当前数是一个偶数,并且不为2的次幂,那么它一定能转成第一状态,因为假设当前数为m*2^k,那么我们减去一个m,剩下的数必定为m*(2^k-1),两个奇数相乘必定是奇数。

综上,我们看到,在2状态下必胜,只有在1状态下在会输。

现在我们来看一下2的次幂怎么做,2的次幂要么转成1,要么转成2,因为转成2必胜,所以当前操作肯定是为了转成1,所以就是每次除以2,这就要看2上面的指数的奇偶了。

所以我们判断里两个,对于非2的次幂奇数必败,偶数必胜。对于2的次幂,指数奇数必败,指数偶数必胜。

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 int t;
 4 int n;
 5 int check(int x){
 6     int i,j,an=0;
 7     while (x%2==0){
 8         an++;
 9         x/=2;
10     }
11     return x==1?an:0;
12 }
13 int main(){
14     int i,j,an;
15     scanf("%d",&t);
16     while (t--){
17         scanf("%d",&n);
18         if (n%2==1) cout<<"Bob"<<endl;
19         else{
20             an=check(n);
21             if (an==0 || an%2==0) cout<<"Alice"<<endl;
22             else cout<<"Bob"<<endl;
23         }
24     }
25     return 0;
26 }

 

posted on 2022-11-17 16:32  珍珠鸟  阅读(43)  评论(0编辑  收藏  举报