Codeforces Round 855 (Div. 3)(E,F)
在\(div2\)受虐久了,这次\(div3\)打的还蛮顺利的(虽然\(wa\)了好几次)
E
题目大意就是有两个字符串,我们要通过以下两种操作把第一个字符变成第二个字符
操作\(1\)就是我们可以把第\(i\)个字符和第\(i+k\)个字符进行交换,操作\(2\)就是我们可以把第\(i\)个字符和第\(i+k\)个字符进行交换,问是否可以变成第二个字符串
第一个要满足的条件就是字母的种类和数量是否一样,然后再考虑其他的
我们可以发现每相邻的两个是可以交换的,如\(i\)可以和\(i+k+1\)交换,然后再用\(i+k+1\)和\(i+1\)进行交换即可,那么就意味着对于所有可以实现相邻两个可以交换的字符的位置可以随意改变,那么我们就假设这一段的字符都是可以匹配成功的,那么对于那些不可以进行一次交换的,是一定不能动的,只有这些位置上的字符都是是符合的才可能成功,否则就失败
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <set>
using namespace std;
//#define int long long
int tt,n,k;
string s,t;
void solve()
{
cin>>n>>k;
cin>>s>>t;
vector<int>cnt1(30),cnt2(30);
for (int i=0;i<n;i++)
{
cnt1[s[i]-'a']++;
cnt2[t[i]-'a']++;
}
for (int i=0;i<26;i++)
{
if (cnt1[i]!=cnt2[i])
{
cout<<"NO\n";
return ;
}
}
for (int i=0;i<n;i++)
{
if (i-k<0&&i+k>=n)
{
if (s[i]!=t[i])
{
cout<<"NO\n";
return ;
}
}
}
cout<<"YES\n";
return ;
}
signed main ()
{
cin>>tt;
while (tt--)
{
solve();
}
system ("pause");
return 0;
}
F
这个题大意是给你\(n\)个字符串,然后我们需要找到两个字符串,满足这两个字符串里面字母的种类一定是\(25\)种,并且每一种字母的数量一定是奇数个,问这样的搭配有多少个
对于两个字符串的字母种类都只有\(25\)个,那么都是缺少了某一个字符,其他的字母一定是奇数个
然后我们知道
\[odd=even+odd \]那么对于这其余的\(25\)个字母,在每一个字符串里面的数量的奇偶性一定是不同的,而且只要满足以上条件,那么其他的字母一定是不等于\(0\)的,恰好只少了一个字符
那么我们可以对于这\(26\)字母的数量的奇偶性用二进制来表示,然后每一次奇偶性的变化和异或\(1\)是一样的变化
那么对于此时有的一种状态,分别找缺少某一个字母的另外一个状态的数量
例如对于下面(假设总共只有\(5\)个字母)
\(11100\),对于缺少第\(4\)个字母,我们需要找同样缺少第\(4\)个字母的,然后再要让其余的字母的数量都变成奇数个,那么我们只要让\(11100\)除了第四位以外其余的每位都异或上\(1\)(存在的都是不一样的),那么就是\(00001\),那么第\(5\)也是存在的,所以刚好是除了我们所指定的那个字符缺少,其余的一定会存在的
所以我们可以用一个二维的\(unordered__map\)来记录(\(map\)可能会超时),第一维表示我们所指定缺失的那一个状态,第二位指的是这\(26\)个字母的数量的奇偶性分布(用二进制\(01\)表示)
那么对于那些除了某一位不用异或,其他的都要异或,我们可以预先处理
具体的细节就看代码吧
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
using namespace std;
#define int long long
int n;
string s;
int sum=0;
int tar[26];
bool vis[26];
int c[26];
unordered_map<int,int>ans[26];
void init()
{
for (int i=0;i<26;++i) tar[i]=((1<<26)-1)^(1<<i);
return ;
}
signed main ()
{
std::ios::sync_with_stdio(false);//消除输入输出缓存
std::cin.tie(0);//解除cin与cout的绑定,加快速率。
cin>>n;
init();
while (n--)
{
cin>>s;
int m=s.size();
for (int i=0;i<26;i++)
{
c[i]=0;
vis[i]=false;
}
for (int i=0;i<m;i++)
{
int now=s[i]-'a';
vis[now]=true;
c[now]^=1;
}
int cur=0;
for (int i=0;i<26;i++)
{
cur|=(c[i]<<i);
}
for (int i=0;i<26;i++)
{
if (!vis[i])
{
ans[i][cur]++;
}
}
for (int i=0;i<26;i++)
{
if (!vis[i])
{
sum+=ans[i][cur^tar[i]];
}
}
}
cout<<sum<<'\n';
system ("pause");
return 0;
}
标签:855,26,字符,int,字母,Codeforces,字符串,Div,include
From: https://www.cnblogs.com/righting/p/17181690.html