题意:给定两个只包含’a’,'b’的长度相同字符串s,t,要你将他们变成一模一样的串,你每次可以将s中的一个字符与t中的一个字符交换,最后输出次数并输出步骤。
首先明确,相同的部分是不用动的,我们只需动不同的部分。
其次,我们分析一下s[i]!=t[i]的情况,无非就是①s[i]=‘a’,t[i]='b’或②s[i]=‘b’,t[i]=‘a’,也不难分析出,①类型要和①类型(不能和自己)交换才可以相同,可以消除两个不同的地方,②同理。
我们以s为基准,用两个queue,q1,q2分别记录所有①,②的位置。那么就有以下情况:
1.q1.size()为偶数,q2.size()也为偶数,这种情况最为简单,次数就是(q1.size()+q2.size())/2,步骤就是两两输出q1(或q2)中的成员,再两两输出q2(或q1)中的成员。
2.q1.size()为奇数,q2.size()也为奇数,我们可以将这种情况化为第1种情况,将q2中的某一个成员复制到q1中,q2删除掉这个成员就行了,注意最后次数是(q1.size()+q2.size())/2+1即可。
3.q1.size()为奇数,q2.size()为偶数,无解,因为无论怎样也没法转化为第1种情况。
4.q1.size()为偶数,q2.size()为奇数,同3。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
char s[maxn],t[maxn];
queue<int> q1,q2;
queue<int> ans;
int main()
{
int n;
cin>>n;
cin>>s+1>>t+1;
for(int i=1;i<=n;++i)
{
if(s[i]=='a'&&t[i]=='b')
q1.push(i);
else if(s[i]=='b'&&t[i]=='a')
q2.push(i);
}
if((q1.size()+q2.size())%2!=0)
cout<<-1<<endl;
else
{
while(!q1.empty()||!q2.empty())
{
if(!q1.empty())
{
if(q1.size()%2==1)
{
ans.push(q2.front());
ans.push(q2.front());
q1.push(q2.front());
q2.pop();
}
else
{
ans.push(q1.front());
q1.pop();
ans.push(q1.front());
q1.pop();
}
}
else
{
if(q2.size()%2==1)
{
ans.push(q1.front());
ans.push(q1.front());
q2.push(q1.front());
q1.pop();
}
else
{
ans.push(q2.front());
q2.pop();
ans.push(q2.front());
q2.pop();
}
}
}
cout<<ans.size()/2<<endl;
while(!ans.empty())
{
cout<<ans.front()<<" ";
ans.pop();
cout<<ans.front()<<endl;
ans.pop();
}
}
return 0;
}