蓝桥 OJ Alice和Bob的爱恨情仇

蓝桥云课 OJ Alice和Bob的爱恨情仇

雾粉和数论

Alice和Bob的爱恨情仇

问题描述

Bob 和 Alice 最近在学习博弈论,为了学以致用,他们找来了一大堆的小饼干,并通过博弈的方式来吃掉这些小饼干。他们将找来的小饼干分成 𝑛n 堆,每堆小饼干有 𝑎𝑖a**i 个小饼干。他们轮流对这些饼干进行操作,操作规则如下:

  • 由 Alice 先手,每次从一堆小饼干中拿出 𝑘𝑚k**m 个小饼干( 𝑘k 为奇数且 𝑚≥0m≥0,且 𝑘𝑚k**m 不能超出该堆小饼干的总数)。

  • 当一方进行完操作后,如果已经没有剩余的小饼干,则该方获胜,赢得所有的小饼干。

Alice 和 Bob 都想赢得所有的小饼干,所以都会以最佳方法来取小饼干,请问他们之中谁能赢得所有的小饼干?

输入格式

第一行,输入两个正整数 𝑛n (1≤𝑛≤2×106)(1≤n≤2×106) , 𝑘k (1≤𝑘≤109)(1≤k≤109) ,分别表示饼干的堆数和每次取出饼干的底数。

第二行,输入 𝑛n 个整数,表示第 𝑖i 堆小饼干有 𝑎𝑖a**i(1≤𝑎𝑖≤1061≤a**i≤106) 个小饼干。

输出格式

输出一行,包含一个字符串,输出 Alice 和 Bob 之中获胜的那个人。

样例输入 1

 2 3  
 4 1

样例输出 1

 Alice

样例输入 2

 2 1  
 6 6

样例输出 2

 Bob

样例说明

在第一个样例中,Alice 拿走第一堆饼干中的 33 (𝑘1)(k1) 个饼干,此时剩余的饼干数分别为 1,1 ,此时,Bob 无论拿哪堆饼干都会使得剩下那堆饼干只有一个,Alice 只需要在下一轮拿走剩余的饼干即可获胜。

在第二个样例中,由于每次都只能取一个,且有 1212 个饼干,所以先手的人到最后一定会输掉比赛。

思路展示

这道题看似起来很难,一开始接触的时候觉得离谱,该题的m竟然没有告诉我们,我还打算求出来,通过转进制的方式设置while循环,后面看到大佬的一个if判断条件瞬间悟了,虽然这道题挂的是博弈论,实际上直接写暴力就好。首先要判断两个值,一个是n堆饼干的总数以及m,求二者的奇偶性,因为题目设置了先让Alice拿饼干,所以当分四种情况,(奇,奇),(偶,偶),(奇,偶),(偶,奇),讲一种情况,依次类推,当n为奇数,m为奇数的时候,最后一次一定是Alice,通过样例就可以得知,就是因为Alice是先手。代码如下(有点繁琐,轻喷)

 // 三年不鸣则已,易鸣惊人
 // 五年不飞则已,一飞冲天
 #include<bits/stdc++.h>
 using namespace std;
 using ll=int64_t;
 using ULL=unsigned long long;   
 #define INF 0x3f3f3f3f
 #define llINF 0x3f3f3f3f3f3f3f3f
 const int R=4e5+10;
 typedef pair<int,int>PII;
 ll sum=0;
 const int N=1e5+10;
 int a[N];
 void solve(){
     int n,m;cin>>n>>m;
     for(int i=1;i<=n;i++){
       cin>>a[i];
       sum+=a[i];
     }
     if(sum%2!=0&&m%2!=0){
       printf("Alice");
     }
     if(sum%2!=0&&m%2==0){
       printf("Bob");
     }
     if(sum%2==0&&m%2==0){
       printf("Bob");
     }
     if(sum%2==0&&m%2!=0){
          printf("Bob");
     }
 }
 int main()
 {
 ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  
    int T;T=1;
    while(T--){
        solve(); 
    }
 return 0;
 ​

如果这道题没有考虑到奇偶性,时间复杂度相当高,所以写这篇博客的目的是再三提醒自己不要忘了奇偶性,我立马想到了另外一道题目--雾粉和数论。


雾粉和数论

题目描述

给你一个正整数 n,请你输出对每个2<=i<=n,gcd(i*(i-1)/2,i(i+1)/2)之和对10^9+7取模。

输入描述:

 第一行有一个正整数,表示n。
 ​
 题目保证对于所有测试用例:
 2<=n<=10^9

输出描述:

 输出有一行一个正整数,表示答案模 10^9+7 后的值。

示例一

输入

复制

 3
输出
 4

说明

 gcd(1,3)+gcd(3,6)=1+3=4

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网

先来给大家展示WA了n发的代码。

 // 三年不鸣则已,易鸣惊人
 // 五年不飞则已,一飞冲天
 #include<bits/stdc++.h>
 using namespace std;
 using ll = int64_t;
 using ULL = unsigned long long;
 #define INF 0x3f3f3f3f
 #define llINF 0x3f3f3f3f3f3f3f3f
 const int R = 4e5 + 10;
 typedef pair<int, int>PII;
 inline int gcd(int a, int b)
 {
     int r;
     while (b > 0)
     {
         r = a % b;
         a = b;
         b = r;
     }
     return a;
 }
 ll sum = 0;
 void solve() {
     int n; cin >> n;
     for (int i = 2; i <= n; i++) {
         sum += gcd(i * (i - 1) / 2, i * (i + 1) / 2); 
     }
     cout << sum << endl;
 }
 int main()
 {
     ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
     int T;T=1;
     while (T--) {
         solve();
     }
     return 0;
 }

纯暴力直接超时,赛后经高人指点,发现直接通过奇偶性解决。分两种情况,当i为奇数的时候,(i-1)/2和(i+1)是互质,所以最大公约数就是i。当i为偶数的时候,最大公约数为i/2。所以直接化简到到最后直接数列求和(i是从2开始的),同理,还需要对n的奇偶性进行判断,当n为奇数时,偶数项是从1开始到(n-1)/2的求和((n-1)/2项),奇数项是从3开始到n的求和(n/2项),n为偶数亦是如此。以下为AC代码。

 // 三年不鸣则已,易鸣惊人
 // 五年不飞则已,一飞冲天
 #include<bits/stdc++.h>
 using namespace std;
 using ll=int64_t;
 using ULL=unsigned long long;   
 #define INF 0x3f3f3f3f
 #define llINF 0x3f3f3f3f3f3f3f3f
 const int R=4e5+10;
 typedef pair<int,int>PII;
 const  int N=1e9+7;
 void solve(){
     ll sum=0,yiming=0;
     ll n;cin>>n;
     if(n%2!=0){
         sum=((3*n*n+4*n-7)/8)%N;
         cout<<sum<<endl;
     }
     if(n%2==0){
           ll t=n/2;
         yiming=(ll) ( ( (ll)n*(n/2)/2-1) %N + (ll)t*(t+1)/2%N +N)%N;
         cout<<yiming<<endl;
     }
 }
 int main()
 {
 ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  
    int T;T=1;
    while(T--){
        solve();
    }
 return 0;
 }

  • 27
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值