#739 (Div. 3) E 字符串模拟

补个题吧~

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);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值