链接
题意:
给出你一个字符串
S
S
S,然后
T
T
T初始为空,让你每次将S加进T中,并将
S
S
S中一个字符全部去除,知道
S
S
S为空。
例如:
S
=
a
b
b
a
b
a
c
S=abbabac
S=abbabac
T
=
a
b
b
a
b
a
c
T=abbabac
T=abbabac ,
S
S
S去除
a
a
a变成
b
b
b
c
bbbc
bbbc
T
=
a
b
b
a
b
a
c
b
b
b
c
T=abbabacbbbc
T=abbabacbbbc,
S
S
S去除
b
b
b变成
c
c
c
T
=
a
b
b
a
b
a
c
b
b
b
c
c
T=abbabacbbbcc
T=abbabacbbbcc,
S
S
S去除
c
c
c变成空串退出。
给出你
T
T
T让你求S和去除字符顺序。找不出来就输出
−
1
-1
−1
分析:
昨晚做题脑子缺根筋把’a’写成了’0’导致一直再找BUG,找到最后精疲力尽。改出来这个地方,也结束了。但是思路还是捋的挺清晰的。
首先我我们看去除字符顺序。就拿上面那个字符串吧
T
=
a
b
b
a
b
a
c
b
b
b
c
c
T=abbabacbbbcc
T=abbabacbbbcc这里去除字符串我们用
S
T
ST
ST表示
S
T
=
a
b
c
ST=abc
ST=abc,我们看到
T
T
T最后一个一定
S
T
ST
ST的最后一个。那么我们后面依次找最先出现的字符不就是
S
T
ST
ST的逆序吗?确实是这样的这样我们就得出了
S
T
ST
ST.
得到 S T ST ST串我们就知道他如何删的了,但是还是不好看 S S S字符串,我们再看 T = a b b a b a c b b b c c T=abbabacbbbcc T=abbabacbbbcc,我们第一次删的 a a a,所以 a a a只出现了1次(原串的a个数的1倍)。第二次删的 b b b,所以 b b b出现2次(原串的b个数的2倍),同样我们看 c c c也是出现了三次(原串的c个数的3倍)这样我们只需要把每个字符的数量记录下来,然后除以它对应的位数,看看是否整除,整除的话,那么整除后的这个数就是 S S S拥有这个字符的个数。不整除,肯定就 − 1 -1 −1了
但是我们写下了之后,发现最后一个样例过不了 q w e q e e w e w qweqeewew qweqeewew,为什么那?因为他按着顺序删后,后面加的顺序不一致,简单的说就是找出来的 S S S和 S T ST ST不能构成 T T T那怎么办那,我们只需要判断一下就好了,按着题目中给的我们既然已经知道了 S S S和 S T ST ST那么一定可以构造出来一个 T ′ T' T′比较一下 T ′ T' T′与 T T T是否相等就好了。
最后的最后,我们提交后,会发现T5。为什么那? 因为如果 T T T是一个字符循环2e5次,那么我们就会复杂化,我们这拿出来特判下,只有一个字符,直接退出输出就好了。
到此就结束了。
寄语:望大家写代码的时候注意,别因为一些细微的地方像我一样一直在找这个恶毒的小BUG。突然想到了上次做杭电的那道题把
1
<
<
i
1<<i
1<<i写成了
i
<
<
i
i<<i
i<<i一直WA,导致心态崩了,最后调了2个半小时左右,调到1点多才调出来,一个题总共时间 读题+思考+写代码都不如调代码的时间长,而且还是细微不能在细微的地方。所以敲代码的时候稍微注意一点,虽然敲代码的时候会多损耗一点时间,但是在敲代码之后就会轻松好多,起码不会有这么低级的错误"绊"你。
string str, s, ans;
map<ll, bool>mp;
int a[30], b[30],c[30];
bool check(string s1,string s2,string s3){
string tmp="";
for(int i=0;i<s3.size();i++){
tmp="";
for(int j=0;j<s2.size();j++){
if(s2[j]!=s3[i]) tmp=tmp+s2[j];
}
s2=tmp;
s1+=tmp;
}
if(s1==str) return 1;
return 0;
}
void solve()
{
mp.clear();
cin >> str;
ans = "";
ll res = 0;
ll len = str.size();
for(int i = 0; i < 30; i++) c[i]=b[i] = 0;
for(int i = 0; i < len; i++)
{
if(mp[str[i] - 'a'] == 0)
{
mp[str[i] - 'a'] = 1;
res++;///记录一共多少个不同的字符。
}
b[str[i] - 'a']++;///
}
if(res==1){
cout<<str<<" "<<str[0]<<endl;
return ;
}
mp.clear();
ll q=res;
for(int i = len-1; i >=0; i--)
{
if(mp[str[i] - 'a'] == 0)
{
mp[str[i] - 'a'] = 1;
ans=str[i]+ans;///删除顺序
c[str[i]-'a']=q--;///每次删完一个字符后,他就不循环了。
}
}
for(int i = 0; i < 26; i++)
{
if(c[i]){
if(b[i]%c[i]!=0){
puts("-1");
return ;
}else {
b[i]=b[i]/c[i];
}
}
}
ll num = 0;
for(int i = 0; i < len; i++)
{
if(b[str[i] - 'a'] == 1)
{
num++;
}
if(b[str[i] - 'a'] == 0)
{
puts("-1");
return;
}
b[str[i] - 'a']--;
if(num == res)
{
s="";
for(int j = 0; j <= i; j++)
{
s=s+str[j];
}
if(check(s,s,ans)){
cout <<s<< " "<<ans<<endl;
return ;
}else {
puts("-1");
return ;
}
}
}
}