其他分享
首页 > 其他分享> > power oj 2868 你头像好乖啊

power oj 2868 你头像好乖啊

作者:互联网

题目链接

博弈论,这种简单的博弈论只要从头数二三十个数,就能找到规律
从2开始,A只能拿一个,B赢,
3,A拿一个,B拿一个,A拿最后剩下的,A赢
4,A拿一个的时候B赢,A拿两个的时候B赢,A拿3个的时候平手,所以取平手
5,A拿一个的时候赢
这个时候就可以看到规律了:n为奇数的时候,A只要拿一个,A就会稳赢
所以奇数可以先不考虑了。
并且我们可以发现2 似乎是一个特例

看偶数,
n为6的时候,只要A拿两个,A赢
n为8的时候,A拿1、2、4都是B赢,3、5、6、7时是平手
n为10,只要A拿两个,A赢
到这能看出一点规律,偶数个物品,只要能被平均分为奇数个部分,A就能赢
换句话说,只要n有奇数因子,就是A赢
那么,只要把偶数因子都剔除掉,最后剩下一个大于1的奇数因子不就行了?

while(n%2==0){
    n/=2;
}

于是,成功的
在这里插入图片描述
不过我们可以换一个角度,我们只要判断,n只有偶数因子时为平手这个情况就好了,那什么情况下n只有偶数因子呢?

我们跑上面的循环,跑到n只剩1的时候,这说明这时的n只有偶数因子。
我们吧测个过程反过来,另1不断地乘以2,最终就可以得到n

所以,n只有偶数因子这种情况,只有在n为2的整数次幂时,才会出现。
我们只需要把2的整数次幂存起来,输入n的时候判断一下就好了

	set<ll> s;
    ll tmp = 2;
    for (int i = 1; i <= 36; i++) {
        tmp <<= 1;
        s.insert(tmp);
    }

于是,整道题搞定!
下面是完整代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main() {
 ios::sync_with_stdio(0);
 cin.tie(0);
 set<ll> s;
 ll tmp = 2;
 for (int i = 1; i <= 36; i++) {
     tmp <<= 1;
     s.insert(tmp);
 }
 ll t, n;
 cin >> t;
 while (t--) {
     cin >> n;
     if (n == 2)//为2,A输
         cout << "NO" << '\n';
     else {
         if (n & 1)//为奇数,A赢
             cout << "YES" << '\n';
         else {
             if (s.count(n))//为2的整数次幂,平手
                 cout << "PING" << '\n';
             else//为其他偶数,赢
                 cout << "YES" << '\n';
         }
     }
 }
 return 0;
}

标签:平手,好乖,oj,奇数,2868,偶数,因子,时候,只要
来源: https://blog.csdn.net/luyuyingyingying/article/details/98375760