codeforces,1215C(模拟 / 思维)

16 篇文章 0 订阅
7 篇文章 0 订阅

题意:给定两个只包含’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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值