cf1537 Round #726 Div2-D【博弈】

本文解析了关于游戏a、b的胜负规则,关键在于判断n能否被偶数次约分。偶数次约分意味着Alice赢,而2的奇数次幂则判定为Bob胜利。通过代码实现和特判2的奇数次幂,解决了比赛中的特殊情形。

Date:2022.02.04
题意:a、b游戏,每次抽出n的一个约数,其中这个约数不等于1或n自身,之后n变成n-抽出的约数。a是先手,直到n中无法抽出任何一个约数,当前抽的那个人输。问最后谁赢。
在这里插入图片描述
思路:枚举一个数的所有约数,若任意一个约数是偶数(注意,每一步约数不能算1和自身),则表示n能分为偶数次拿出,每次拿出是n/此偶数,因此a获胜。若不存在,b获胜。之后喜提wa2,打表之后显然遗漏了一种特殊情况。例如:8满足条件,但以每一次拿4为例 ------ a先拿出4、b拿出2,还剩下2该a拿,a不就寄了吗?打表发现这些数都是2?2^?2?,其中???为奇数,因此特判即可。其实2的奇数次幂一定是b赢好理解,就以8、32为例模拟一下,每次不论a先怎么分、分多少,每次取最大n/2…取最小2,取多少b都会让a寄。此外这题卡LL。
代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t;cin>>t;
    while(t--)
    {
        vector<int>v;int n;cin>>n;int x=n,cnt=0;bool flag=false;
        if(n==2) {cout<<"Bob"<<endl;continue;}
        while(x%2==0) {x/=2;cnt++;}
        if(x==1&&cnt%2==1) {cout<<"Bob"<<endl;continue;}//2的奇数次幂
        x=n;
        for(int i=1;i<=x/i;i++)
            if(x%i==0&&i!=1&&i!=x)
            {
                v.push_back(i);
                if(i%2==0) {flag=true;break;}
                if(i!=x/i) 
                {
                    v.push_back(x/i);
                    if(i%2==0) {flag=true;break;}
                }
            }
        if(flag) cout<<"Alice"<<endl;
        else cout<<"Bob"<<endl;
    }
    return 0;
}
graph TD subgraph 哈夫曼树 (Huffman Tree) A(100) --> B(40) A --> C(60) B --> D(19) B --> E(21) C --> F(28) C --> G(32) F --> H(11) F --> I(17) H --> J(5) H --> K(6) I --> L(7) I --> M(10) J --> N(2) J --> O(3) end style A fill:#f9f,stroke:#333,stroke-width:2px style B fill:#ccf,stroke:#333,stroke-width:2px style C fill:#ccf,stroke:#333,stroke-width:2px style D fill:#9cf,stroke:#333,stroke-width:2px style E fill:#9cf,stroke:#333,stroke-width:2px style F fill:#9cf,stroke:#333,stroke-width:2px style G fill:#9cf,stroke:#333,stroke-width:2px style H fill:#69f,stroke:#333,stroke-width:2px style I fill:#69f,stroke:#333,stroke-width:2px style J fill:#69f,stroke:#333,stroke-width:2px style K fill:#69f,stroke:#333,stroke-width:2px style L fill:#69f,stroke:#333,stroke-width:2px style M fill:#69f,stroke:#333,stroke-width:2px style N fill:#36f,stroke:#333,stroke-width:2px style O fill:#36f,stroke:#333,stroke-width:2px linkStyle 0 stroke-width:2px,fill:none,stroke:black; linkStyle 1 stroke-width:2px,fill:none,stroke:black; linkStyle 2 stroke-width:2px,fill:none,stroke:black; linkStyle 3 stroke-width:2px,fill:none,stroke:black; linkStyle 4 stroke-width:2px,fill:none,stroke:black; linkStyle 5 stroke-width:2px,fill:none,stroke:black; linkStyle 6 stroke-width:2px,fill:none,stroke:black; linkStyle 7 stroke-width:2px,fill:none,stroke:black; linkStyle 8 stroke-width:2px,fill:none,stroke:black; linkStyle 9 stroke-width:2px,fill:none,stroke:black; linkStyle 10 stroke-width:2px,fill:none,stroke:black; linkStyle 11 stroke-width:2px,fill:none,stroke:black; linkStyle 12 stroke-width:2px,fill:none,stroke:black; linkStyle 13 stroke-width:2px,fill:none,stroke:black; linkStyle 14 stroke-width:2px,fill:none,stroke:black; subgraph 字符与权值 D --- b(19) E --- g(21) G --- e(32) K --- d(6) L --- a(7) M --- h(10) N --- c(2) O --- f(3) end
11-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值