见P1928 外星密码 - 洛谷
题目描述
有了防护伞,并不能完全避免 2012 的灾难。地球防卫小队决定去求助外星种族的帮助。经过很长时间的努力,小队终于收到了外星生命的回信。但是外星人发过来的却是一串密码。只有解开密码,才能知道外星人给的准确回复。解开密码的第一道工序就是解压缩密码,外星人对于连续的若干个相同的子串 X 会压缩为 [DX] 的形式(D 是一个整数且 1≤D≤99),比如说字符串 CBCBCBCB 就压缩为 [4CB] 或者[2[2CB]],类似于后面这种压缩之后再压缩的称为二重压缩。如果是 [2[2[2CB]]] 则是三重的。现在我们给你外星人发送的密码,请你对其进行解压缩。
输入格式
输入一行,一个字符串,表示外星人发送的密码。
输出格式
输出一行,一个字符串,表示解压缩后的结果。
输入输出样例
in:
AC[3FUN]
out:
ACFUNFUNFUN
说明/提示
【数据范围】
对于 50% 的数据:解压后的字符串长度在 1000 以内,最多只有三重压缩。
对于 100% 的数据:解压后的字符串长度在 20000 以内,最多只有十重压缩。保证只包含数字、大写字母、[
和 ]
。
初步思路
输入的这个字符串是被多重「压缩」的,所以一重一重地「解压缩」可能会非常非常麻烦(不过应该是可行的),导致代码极其难以理解。
所以,我们使用递归算法,在读入这个字符串之后,找出被压缩的内容,再对被压缩的那个字符串实行「解压缩」操作。
举个例子:AC[3FUN]
首先,我们找到了被压缩的字符串:3FUN
对3FUN
进行解压,得到FUNFUNFUN
再把原来的字符串AC
后面添上FUNFUNFUN
即可。
由于这个只有一重「压缩」,可能递归思想体现的不太明显,这里再举一个多重「压缩」的例子:
SAD[4MLE[2TLE[2RE[2WA]]]
首先找到被「压缩」的部分:
[2MLE[2TLE[2RE[2WA]]]]
(从此处开始剩下的部分就是递归的内容了,全部由程序自主实现)
对这个部分进行解压,找到被「压缩」的部分:
[2TLE[2RE[2WA]]]
再对这个部分进行解压,找到被「压缩」的部分:
[2RE[2WA]]
再对这个部分进行解压,找到被「压缩」的部分:
[2WA]
(开始一层一层跳出递归)
对这个部分进行解压并加到前一个字符串的末尾:
[2REWAWA]
再对这个部分进行解压并加到前一个字符串的末尾:
[2TLEREWAWAREWAWA]
再对这个部分进行解压并加到前一个字符串的末尾:
[2MLETLEREWAWAREWAWATLEREWAWAREWAWA]
再对这个部分进行解压并加到前一个字符串的末尾:
SADMLETLEREWAWAREWAWATLEREWAWAREWAWAMLETLEREWAWAREWAWATLEREWAWAREWAWA
至此,递归结束,「密码」破译完毕。
所以,我们只需要找到被「压缩」的子串,并把这个字符串扔给「解压缩」程序即可。
本题可以使用递归的算法(已经有很多大佬指出了):
主函数只需调用递归函数即可,因为递归函数既实现输入,又实现了字符串的处理。
注意事项
最重要的是: 千万不要跳进这个函数里面企图探究更多细节,否则就会陷入无穷的细节无法自拔。——OI Wiki
我们也看到了,上面对SAD[4MLE[2TLE[2RE[2WA]]]
的分析细节很多很多,十分复杂。
完整代码:
#include<bits/stdc++.h>
using namespace std;
string y(){
string s,t;
char c;
while(cin>>c){
if(c=='['){
int n;
cin>>n;
t=y();
while(n--)s+=t;
}
else{
if(c==']')return s;
else s+=c;
}
}
}
int main(){
cout<<y();
return 0;
}
动动您来财的手指
关注+收藏+点赞
好吗