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;
}