【Codeforces】Codeforces Round #739 (Div. 3) E. Polycarp and String Transformation

83 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情

【Codeforces】Codeforces Round #739 (Div. 3) E. Polycarp and String Transformation

题目链接

Problem - E - Codeforces

题目

image.png

题目大意

对于给定的一个字符串 ss,和一个空串 tt,执行若干次下述操作:

  • t += st += s
  • 然后选一个 ss 中含有的字符 cc,将其从 ss 中全部删掉

重复该操作直到 ss串为空。

现给出 tt 串,求原字符串 ss 和删除字符的顺序。

思路

先求删除顺序,倒着遍历字符串 tt,如果遍历到当前位置 ii 时,字符 tit_i 过去没有出现过,那么本轮删除的字符串就是 tit_i

这样我们就求出了删除字符的顺序。

假设数组 v[ch]v[ch] 表示字符 chchtt 串中出现了 v[i]v[i] 次,且它是全场第 ii 个被删除的,那么它在字符串 ss 中出现了 v[ch]i\frac{v[ch]}{i} 次。

v[ch]i\frac{v[ch]}{i} 求和,则 sumsum 就是原串 ss 的长度,且 tt 中的前 sumsum 个字符就构成了 ss。在求和过程中,若出现不能整除的情况,则无解。

求出 ss 后,我们按照题意模拟地构造 tt',若 ttt\neq t',也输出无解。

若有解,输出我们已经求出来的原串 ss 和删除序列即可。

代码

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
using namespace std;
using LL=long long;
const int N=1e6+5;
const LL mod=1e9+7;
int n,m,k;
char a[N],dt[N],b[N],s[N];
int v[26],tot;
LL solve()
{
	tot=0;
	memset(v,0,sizeof(v));
	scanf("%s",a+1);
	n=strlen(a+1);
	for (int i=n;i>=1;--i)
	{
		if (v[a[i]-'a']==0) dt[++tot]=a[i];
		v[a[i]-'a']++;
	}
	for (int i=1;i<=tot/2;++i) swap(dt[i],dt[tot-i+1]);
	int sum=0;
	for (int i=1;i<=tot;++i)
	{
		if (v[dt[i]-'a']%i) return 1;
		sum+=v[dt[i]-'a']/i;
	}
	memset(v,0,sizeof(v));
	for (int i=1;i<=sum;++i) s[i]=a[i];
	int cnt=sum;
	for (int i=1;i<=tot;++i)
	{
		if (i!=0) v[dt[i]-'a']=1;
		for (int j=1;j<=sum;++j)
		{
			if (v[s[j]-'a']) continue;
			++cnt;
			if (a[cnt]!=s[j]) return 1;
		}
	}
	for (int i=1;i<=sum;++i) printf("%c",s[i]);
	printf(" ");
	for (int i=1;i<=tot;++i) printf("%c",dt[i]);
	printf("\n");
	return 0;
}
int main()
{
	int T=1;
	scanf("%d",&T);

	while (T--) 
		if (solve()) printf("-1\n");
	return 0;
}