目录
A. Cirno's Perfect Bitmasks Classroom
B. Patchouli's Magical Talisman
A. Cirno's Perfect Bitmasks Classroom
A. Cirno's Perfect Bitmasks Classroom
思路:
若lowbit(n)的1为n的唯一的1,则输出该数+1(令最后一位为1,保证异或^操作);否则输出lowbit(n)(其他位上的1保证了异或^操作)
其中,当 n == 1 时,特殊判断,因为 + 1不能保证异或^操纵的成立,所以不一定成立
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 2e5 + 10, mod = 1e9 + 7;
int T;
int lowbit(int x)
{
return x & -x;
}
void solve()
{
int n;
scanf("%d", &n);
if(n < 3) cout << 3 << endl;
else if(n - lowbit(n) == 0) cout << lowbit(n) + 1 << endl;
else cout << lowbit(n) << endl;
}
int main()
{
scanf("%d", &T);
while(T -- )
solve();
return 0;
}
B. Patchouli's Magical Talisman
B. Patchouli's Magical Talisman
思路:只需让任意的一个奇数与其他偶数合并除以二即可,存在奇数则直接合并,不存在则令lowbit最小的偶数变为奇数,在与其他的偶数合并即可
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 2e5 + 10, mod = 1e9 + 7;
int T;
int qmi(int a, int k)
{
int res = 1;
while(k)
{
if(k & 1) res = (LL)res*a % mod;
k >>= 1;
a = (LL)a*a%mod;
}
return res;
}
LL lowbit(LL x)
{
return x & -x;
}
void solve()
{
int n, k;
scanf("%d", &n);
LL a[N];
LL res = 0;
LL sum = 1 << 30, f = 0;
for(int i = 0; i < n; i ++ )
{
scanf("%lld", &a[i]);
if(a[i] % 2 == 0) sum = min(lowbit(a[i]), sum), res ++;
else f = 1;
}
if(f)
{
printf("%d\n", res);
return;
}
else printf("%d\n", res - 1 + (int)log2(sum));
}
int main()
{
scanf("%d", &T);
while(T -- )
solve();
return 0;
}
C. Manipulating History
思路:
令一个字符串替换为另一个字符串过程为,
1原字符串包含要替换的字符串,2将要替换的字符串与替换后的字符串列出,3替换
我们可知,在每一部替换中,要替换的字符串(即不是答案的字符串)一定出现了两次,最后剩余的字符串,一定是奇数。
遍历所有字符串(包括要替换的字符串,与,替换过的字符串),字符的数量为奇数的一定为最初的字符串
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 200010;
int T;
void solve()
{
int n;
scanf("%d", &n);
unordered_map<char, int> mp;
string s;
for(int i = 0; i < 2*n+1; i ++ )
{
cin >> s;
for(int i = 0; i < s.size(); i ++ )
mp[s[i]] ++;
}
for(auto it : mp)
{
if(it.second % 2)
{
cout << it.first << endl;
return;
}
}
}
int main()
{
scanf("%d", &T);
while(T -- )
solve();
return 0;
}
D. The Enchanted Forest
思路:
分情况讨论+贪心
若 k < n,则找到最大长度为k的连续子序列,计算每天生长的高度,得出结果即可,计算的区间为 [i-k+1, i] 区间,找出最大
若 k >= n ,则只走最后的 n 步可以使答案最大,然后计算每天生长的高度,计算即可
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 200010;
int T;
int n, m, a[N];
LL s[N];
void solve() {
cin >> n >> m;
s[0] = 0;
LL res = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
s[i] = s[i - 1] + a[i];
if (i >= m) res = max(res, s[i] - s[i - m]);
}
if (m <= n) {
res += (LL)m * (m - 1) / 2;
cout << res << endl;
}
else {
int k = m;
res = s[n];
res += (LL)(k*2-n-1)*n/2;
cout << res << endl;
}
}
int main()
{
scanf("%d", &T);
while(T -- )
solve();
return 0;
}