/** 鼠标样式 **/

Shu-How Zの小窝

Loading...

CF1697C

C. awoo's Favorite Problem

首先,检查两个字符串中所有字母的计数是否相同。

然后考虑下面的重述。字符串s中的字母 b是静止的。而字母a和c则在字符串中移动。第一种移动是将字母a向右移动。第二种类型的移动将字母c向左移动。
请注意,字母 a和c永远不能互换。因此,如果从两个字符串中移除所有字母 b,剩余的字符串应该是相同的。

例如:

s = bcaabababc
t = cbbababaac

去除字符b后:

s = caaaac
t = caaaac

同样,由于字母a和c永远不会互换,因此可以推断出互换后这两个字母各自的位置。s中的第一个字母a应该位于t中的第一个字母a的位置,以此类推。

然后,我们回顾一下,a只能向右移动,而c只能向左移动。因此,我们要检查 s中a的i次出现的位置是否在t中a的i次出现的位置的左边,或者s中c的i次出现的位置是否在 t中c的i次出现的位置的右边,

例如:

s 中 a 的位置为3,4,6,8; c 的位置为2,10.

t 中 a 的位置为4,6,8,9; c 的位置为1,10.

但是有没有可能存在一种反例使上述都成立但是却不符合题目要求?

例如:s 中某一段为...abbbb..., t中与之对应的为...bbbbxa..., x为a或c, 若x为a,则s中该段的字符a所对应的字符为x,与原假设矛盾。反之,如果x为c,则s中a的左边必定存在一个c与之对应,但是又因为s中c的i次出现的位置在t中c的i次出现的位置的右边,故与之矛盾,不存在反例。

总体复杂度:每个测试案例 O(n)。

代码(jls):

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const ll N=2e5+10;
ll t;
string s1,s2;
ll n;
void solve()
{
	cin>>n;
	cin>>s1>>s2;
	for(auto s:{'a','b','c'}) 
	{
        if(std::count(s1.begin(),s1.end(),s)!=std::count(s2.begin(),s2.end(),s)) 
		{
            cout<<"NO"<<endl;
            return;
        }
    }
    string a="",b="";
    vector<ll> k1,k2;
	for(int i=0;i<n;++i)
	{
		if(s1[i]!='b')
		{
			a+=s1[i];
			k1.push_back(i);
		} 
	} 
	for(int i=0;i<n;++i)
	{
		if(s2[i]!='b')
		{
			b+=s2[i];
			k2.push_back(i);
		} 
	} 
	//cout<<a<<endl<<b<<endl;
	if(a!=b){
		cout<<"NO"<<endl;
		return;
	}
	for(int i=0;i<k1.size();++i)
	{
		if(a[i]=='a'&&k1[i]>k2[i])
		{
			cout<<"NO"<<endl;
			return;
		}
		if(b[i]=='c'&&k1[i]<k2[i])
		{
			cout<<"NO"<<endl;
			return;
		}
	}
	cout<<"YES"<<endl;
}
int main()
{
	cin>>t;
	while(t--)
	solve();
	return 0;
}
posted @   Violet_fan  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示