补个题吧~
E. Polycarp and String Transformation
题意:
初始一个字符串
s
s
s 和一个空串
t
t
t,每次操作把
s
s
s 加到
t
t
t 后边,并且选择
s
s
s 字任意一种字符,并删除全部的这种字符,直至
s
s
s 串为空。给你一个操作完的串
t
t
t,求串
s
s
s,不存在输出
−
1
-1
−1。
思路:
从后往前扫一遍
t
t
t 串,每次新出现一种字符,就是倒数第几个被删除的,vector存一下然后 reverse一下就可以得到删除字符的顺序。设
c
n
t
i
cnt_i
cnti 为第
i
i
i 个被删除的字符在
t
t
t 串中出现的次数,那么这个字符在
s
s
s 串中出现的次数就是
c
n
t
i
i
\frac{cnt_i}{i}
icnti。然后求得所有字符在
s
s
s 串中出现的总长度
l
e
n
len
len 即为
s
s
s 串的长度,那么如果存在这样的
s
s
s 串,那么
t
.
s
u
b
s
t
r
(
0
,
l
e
n
)
t.substr(0,len)
t.substr(0,len) 就是
s
s
s串。
我们得到这个假定的
s
s
s 串之后再模拟一遍构造
t
t
t 串的过程,来判断这个
s
s
s 串是否合法
#include<bits/stdc++.h>
#define _ 0
#define ll long long
using namespace std;
const int maxn = 1e5 + 9;
const int mod = 1e9 + 7;
int n;
int vis[30];
void work()
{
memset(vis, 0, sizeof(vis));
string s;
vector <char> v;
cin >> s;
n = s.length();
for(int i = n - 1; i >= 0; --i)
{
int now = s[i] - 'a' + 1;
if(!vis[now])
vis[now] = 1, v.push_back(s[i]);
else ++vis[now];
}
reverse(v.begin(), v.end());
int len = 0;
for(int i = 0; i < v.size(); ++i)
{
int now = v[i] - 'a' + 1;
if(vis[now] % (i + 1) == 0)
vis[now] /= i + 1, len += vis[now];
else {
cout << -1 << endl; return;
}
}
string ans = s.substr(0, len);
string tmp = "";
memset(vis, 0, sizeof(vis));
for(int i = 0; i < v.size(); ++i)// 模拟构造过程判断是否合法
{
for(int j = 0; j < ans.size(); ++j)
{
int now = ans[j] - 'a' + 1;
if(!vis[now]) tmp += ans[j];
}
vis[v[i] - 'a' + 1] = 1;
}
if(tmp != s){
cout << -1 << endl;return;
}
cout << ans << " ";
for(auto x : v) cout << x;cout << endl;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int TT;cin>>TT;while(TT--)
work();
return ~~(0^_^0);
}
1826

被折叠的 条评论
为什么被折叠?



