Codeforces Round #739 (Div. 3) 1560E - Polycarp and String Transformation(逆向思维)

题目

题目传送门

题目大意

给定一个字符串S,该字符串是由字符串T经过以下操作得来的:
初始S=T
选定T中的一个字母,删去T中全部该字母,得到新T’;
S+=T’;
重复以上步骤直到T被删完为止。
现在给定结果串S,让你求初始串T和字母的删除顺序。

解题思路

初步分析似乎很复杂,如何确定删去字母,如何确定初始长度,似乎两者有着相互影响的关系。
这是按照题目的意思去正向推理,问题变复杂了。
那么便试试逆向推理。最后的一个T一定是由单一字母组成,倒数第二个由两个,以此类推。显然这样就求得了删除字符串的顺序。
那么有了这个顺序又如何求解初始串?
一拍脑袋!每个字母出现的次数和其删除的次序有关,如果第一个被删去,那么只出现一次,即S中的都是初始的,第二个被删去,S串中的个数便是初始串中的两倍,于是通过该方式就可以得到初始串的长度。
之后再通过模拟来验证。便完成了对该问题的求解。

code

#include<bits/stdc++.h>
using namespace std;
void solve()
{
	string s;
	cin>>s;
	vector<int>m(27,0),a;
	for(int i=s.length()-1;i>=0;i--)
	{
		if(m[s[i]-'a']==0)a.push_back(s[i]);
		m[s[i]-'a']++;
	}
	reverse(a.begin(),a.end());//获得的是倒序,需要翻转
	int n=a.size();
	int sum=0; 
	//for(int i=0;i<a.size();i++)cout<<(char)a[i];cout<<endl;
	for(int i=0;i<n;i++)
	{
		if(m[a[i]-'a']%(i+1)==0)sum+=m[a[i]-'a']/(i+1);//确定初始串长度,不能整除,显然无法构造
		else 
		{
			cout<<-1<<endl;return ;
		}
	}
//	cout<<sum<<endl;
	string ns;
	for(int i=0;i<sum;i++)ns+=s[i];
	string nss=ns,resu=ns;
	for(int i=0;i<a.size();i++)
	{
		string temp;
		for(int j=0;j<nss.length();j++)
		{
			if(nss[j]==a[i])continue;
			temp+=nss[j];
		}
		resu+=temp;
		nss=temp;
	}
	if(resu==s)//模拟验证
	{
		cout<<ns<<" ";
		for(int i=0;i<a.size();i++)cout<<(char)a[i];cout<<endl;//
	}
	else cout<<-1<<endl;
}
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值