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