90分的模拟做法(10分TLE)
查看原帖
90分的模拟做法(10分TLE)
999513
zjc20080627楼主2024/12/1 22:25

循环比较第i个位置的字符,如果相同那么记录答案ans++,否则在可以交换的区域里找另一边相同的字符,代码如下:

#include <bits/stdc++.h>
using namespace std;
int k1[2000000];//k[i]表示离s[i]最近的固定字符的位置
int k2[2000000];
string s1;
string s2;
string f1;
string f2;
int t;
int n;
string subs1;//可以交换的区域单独提取出来
string subs2;
int tmp1,tmp2;
int ans;
int len1,len2;//自由交换区间的长度
int find1,find2;
int main()
{
	//freopen("edit.in","r",stdin);
	//freopen("edit.out","w",stdout);
	ios::sync_with_stdio(false);
	cin>>t;
	while (t--)
	{
		ans=0;
		cin>>n;
		cin>>s1;
		cin>>s2;
		cin>>f1;
		cin>>f2;
		tmp1=n;
		tmp2=n;
		for (int i=n-1;i>=0;i--)
		{
			if (f1[i]=='0')
				tmp1=i;
			k1[i]=tmp1;
		}
		for (int i=n-1;i>=0;i--)
		{
			if (f2[i]=='0')
				tmp2=i;
			k2[i]=tmp2;
		}
		for (int i=0;i<n;i++)
		{
			if (s1[i]==s2[i])//都相同了等什么,直接加答案
			{
				ans++;
				continue;
			}
			if (k1[i]-i-1>=1)//如果有字符可以跟它交换
			{
				len1=k1[i]-i-1;
				subs1=s1.substr(i+1,len1);
				find1=subs1.find(s2[i]);//在自由交换区间里找跟s2对应位置一样的
				if (find1!=subs1.npos)
				{
					swap(s1[find1+i+1],s1[i]);//找到交换,计答案
					ans++;
					continue;//注意不要再考虑s2[i]了
				}
			}
			if (k2[i]-i-1>=1)//同上
			{
				len2=k2[i]-i-1;
				subs2=s2.substr(i+1,len2);
				find2=subs2.find(s1[i]);
				if (find2!=subs2.npos)
				{
					swap(s2[find2+i+1],s2[i]);
					ans++;
					continue;
				}
			}
		}
		cout<<ans<<endl;
	}
	//fclose(stdin);
	//fclose(stdout);
	return 0;
}

有没有大佬帮我看看这个思路能不能优化到ac,orz

2024/12/1 22:25
加载中...