开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情
【Codeforces】Codeforces Round #739 (Div. 3) E. Polycarp and String Transformation
题目链接
题目
题目大意
对于给定的一个字符串 ,和一个空串 ,执行若干次下述操作:
- 令
- 然后选一个 中含有的字符 ,将其从 中全部删掉
重复该操作直到 串为空。
现给出 串,求原字符串 和删除字符的顺序。
思路
先求删除顺序,倒着遍历字符串 ,如果遍历到当前位置 时,字符 过去没有出现过,那么本轮删除的字符串就是 。
这样我们就求出了删除字符的顺序。
假设数组 表示字符 在 串中出现了 次,且它是全场第 个被删除的,那么它在字符串 中出现了 次。
对 求和,则 就是原串 的长度,且 中的前 个字符就构成了 。在求和过程中,若出现不能整除的情况,则无解。
求出 后,我们按照题意模拟地构造 ,若 ,也输出无解。
若有解,输出我们已经求出来的原串 和删除序列即可。
代码
#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;
}