@[TOC](Codeforces Round #796 (Div. 2))
A.Cirno’s Perfect Bitmasks Classroom
题目大意:奇诺给他的学生一个正整数x,并且布置了一项作业,要求她的学生找到最小的正整数满足这两个条件:x&y>0并且x xor y > 0;
思路:有位运算,肯定要跟二进制数联系起来,首先,我们需要知道,一个偶数的二进制数的最左边一定是0,而奇数的二进制数的最左边一定是1。分奇偶考虑,若为奇数,要想满足上面两个式子,若x != 1,则y = 1,若x=1,则y = 3;若为偶数,需要找到该数从左往右第一个为1的位置,然后,在x为偶数时,若第一个出现1的位置不是最后一个出现1的位置,那么直接把该位往左的数全部看成0,输出即可,若只有一个1时,输出x+1即可(不理解的可以举几个例子试试)。
/*
author : Mzx
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn = 1e5+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second
int read () {
int k=0,f=1;
char c=getchar ();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
return k*f;
}
void solve() {
int n; cin >> n;
if(n & 1)
{
if(n == 1)
{
cout<<"3"<<endl;
}
else
{
cout<<"1"<<endl;
}
}
else
{
int m = 0;
int p = n;
while((p&1) == 0) {
p = p >> 1;
m++;
}
int ans = 2 << (m-1);
if(ans == n)
cout << ans + 1<< endl;
else
cout<<ans<<endl;
}
}
int main()
{
ios;
int t;cin >> t;
while(t--)
{
solve();
}
return 0;
}
B. Patchouli’s Magical Talisman
题目大意:广藿香正在制作一个神奇的护身符。她最初有n魔法令牌。他们的神奇力量可以用正整数a1,a2, … ,an来表示。
广藿香可以对令牌执行以下两种操作。
融合:广藿香选择两个标记,移除它们,并创造一个新的标记,其魔力等于两个所选标记之和。
减法:广藿香选择魔力值相等的令牌X,将其移除并创建一个新的令牌,其魔力等于X/2.
当它们的魔力是奇数时,令牌会更有效。请帮助广藿香找出她需要的最少操作次数,以使所有代币的魔力为奇数。
思路:首先先算出a数组中偶数和奇数的个数分别为多少,如果全为奇数,答案为0,如果全为偶数,那么为了找出最少操作次数,先把一个最小的偶数通过“减法操作”变成1,再进行n-1次融合操作。(偶数和偶数相加还是偶数,偶数和奇数相加是奇数)如果有奇数有偶数,则直接输出偶数个数即可。(偶数与奇数相加)
/*
author : Mzx
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn = 2e5+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second
int read () {
int k=0,f=1;
char c=getchar ();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
return k*f;
}
void solve()
{
int n; cin>>n;
int num_even = 0; //偶数的数量
int ans = INF;
for(int i = 1;i <= n;i ++)
{
int x;cin>>x;
if(x%2==0) num_even++;
int pos = 0; //记录一个偶数递归/2,到1需要的步数
while(x%2==0)
{
pos++;
x/=2;
}
ans = min(ans,pos);
}
if(num_even != n) cout << num_even << endl;
else cout << ans + num_even - 1 << endl;
}
int main()
{
ios;
int t; cin>>t;
while(t--)
{
solve();
}
return 0;
}
C. Manipulating History
题目大意:
凯因有能力操纵历史。
幻想乡的历史最初是一个长度为1的字符串s。要修复由香里造成的混乱,她需要做以下操作n次,对于每一次操作:
1.她选择了一个s的非空子字符串 t2i-1.
2.她用一个非空的字符串 t2i来替换t2i-1.注意,这两个字符串的长度可以不同。
请注意,如果t2i-1不止一次出现在s,则其中一个将被替换。
例如,让s=“marisa”,t2i-1=“a”,和t2i=“ z ”,操作后,s变成“ mzrisa ”或“ marisz ”。
在n次操作后,Keine 得到了最终的字符串和一个操作序列t长度为2n. 就在凯涅认为她已经完成的时候,由香里再次出现并洗牌了。更糟糕的是,Keine 忘记了最初的历史。
帮助 Keine 找到幻想乡的最初历史!
回想一下,子字符串是字符串的一系列连续字符。例如,对于字符串“ abc ”,它的子字符串是:“ ab ”、“ c ”、“ bc ”等。但以下字符串不是它的子字符串:“ ac ”、“ cba ”、“ acb ”
思路:该题是一个结论题,在操作过程中,出现次数为奇数的字符即为最初的字符。因为最初的字符只在第一次进行操作时被输入,其他的字符串均在被操作时和操作后得到的字符串中出现,故两两一对出现,所以出现次数必为偶数。
/*
author : Mzx
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn = 2e5+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second
int read () {
int k=0,f=1;
char c=getchar ();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
return k*f;
}
int ch[maxn];
void solve()
{
memset(ch,0,sizeof ch);
int n; cin >> n;
n = 2 * n + 1;
for (int i = 0; i < n; i++) {
string s;
cin >> s;
for(auto c : s) ch[c - 'a']++;
}
// cout<<ch[0]<<endl;
// cout<<ch[25]<<endl;
for(int i = 0;i < 26;i ++)
{
if(ch[i] & 1)
{
printf("%c\n",'a'+i);
break;
}
}
}
int main()
{
ios;
int t; cin>>t;
while(t--)
{
solve();
}
return 0;
}
膜拜 Yakumo_Ran(紫名大佬), SSerxhs(红名大佬)的位运算解法。Orz!
#include "bits/stdC++.h"
using namespace std;
int main()
{
ios::sync_with_stdio(0);cin.tie(0);
int T;cin>>T;
while (T--)
{
int n;
char c=0;
cin>>n;
n=n*2+1;
while (n--)
{
string s;
cin>>s;
for (auto x:s) c^=x;
}
cout<<c<<'\n';
}
}