2022-04-11每日刷题打卡

这篇博客探讨了两道编程竞赛题目。第一题涉及异或运算,要求找出从0到2^m-1中选取k个数,使它们的异或和等于n,并求出最大可能的k。第二题是棋盘游戏策略问题,Alice和Bob在N×M的棋盘上轮流放置棋子,目标是使得每个K×K的区域都有棋子,分析了在最优情况下谁会获胜。
摘要由CSDN通过智能技术生成

2022-04-11每日刷题打卡

代码源——每日一题

简单的异或问题 - 题目 - Daimayuan Online Judge

有一组整数 {0,1,2,…,2m−1} 请从中选出 k 个数,使得这 k 个数的异或和为 n, 请输出最大的满足条件的 k。

输入格式

两个数 n 和 m, 其中 0≤n≤2^m−1,1≤m≤60。

输出格式

输出最大的满足条件的 k。

样例输入
2 2
样例输出
3
样例解释

对于样例,我们可以选择 {0,1,3}。

首先这有一个结论:0~2^m-1的所有数进行XOR运算后,得到的结果是0。我们来证明一下这个结论:

比如m=3时,一共是0 1 2 3 4 5 6 7,八个数,我们把他们首位组成一对,一共是4对:{0,7}{1,6}{2,5}{3,4}。

它们每一对内部进行XOR运算后的结果都是7,转化成二进制就是111,此时4个111进行XOR运算,得到的自然是0。

那么这个结论有什么用呢,我们知道111和111经过xor运算后会变成0,因为他们每一位上都是相等的,如果我们想通过111获得一个数,在这里假设我们想要的是3(二进制是011),那么就需要111和100进行XOR运算,发现了吗,100正好就是和3配对的另一个数:4.

所以,想在0~2m-1里通过xor运算获得一个数a,就只用(2m-1)和(2m-1-a)进行xor运算即可,但这里要求的是最多能选多少数,我们可以把所有的数(除了目标a)都选上,真正有用的只有(2m-1)和(2m-1-a),至于其他的数经过运算后都会变成0.所以k能取到的最大值就是2m-1。但有两个特殊情况,一个是a=0时,我们可以把所有的数都选上,即k=2^m,还有一个是m=1时,想获得0只能选0,想获得1可以两个都选。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n';
typedef long long ll;
typedef pair<ll, ll> PII;

int main()
{
    
    ll n, m;
    cin >> n >> m;
    ll res = 1;
    res <<= m;
    if (m == 1 && n == 0)
    {
        cout << 1 << endl;
    }
    else if (m == 1&&n==1)
    {
        cout << 2 << endl;
    }
    else cout << (1LL)*(res - min(n,1LL)) << endl;
    return 0;
}
游戏 - 题目 - Daimayuan Online Judge
题目描述

Alice和Bob在玩一个游戏. 有一个长为N, 宽为M的棋盘, 他们轮流在棋盘上的空位置放置一个棋子. 当一位玩家放置完棋子后, 如果对于棋盘上任意一块K∗K的区域, 都存在至少一个棋子. 那么游戏结束, 最后放置的玩家获胜. Alice先放棋子, 在他们的操作都是最优的情况下, 求出谁会赢得这场游戏.

输入格式

第一行三个正整数N, M和K. (N≤M)

输出格式

一行一个字符串, 在Alice先操作的情况下, 如果Alice获胜, 输出"Alice". 否则, 输出"Bob".

数据范围

对于所有数据, 满足: 1≤N≤3000, 1≤N≤M≤10^5, 且1≤K≤N.

样例输入1
1 2 1
样例输出1
Bob
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n';
typedef long long ll;
typedef pair<ll, ll> PII;

int main()
{
    
    ll n, m, k;
    cin >> n >> m >> k;
    if ((n < k * 2 && m < k * 2) || ((n-k) % 2 && (m-k) % 2))cout << "Alice";
    else cout << "Bob";
    
    
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值