事件起因
题目链接
经过我不懈的努力,我终于AC了这道大模拟题。
都怪出题人的题解过于不负责任我太菜了。
先亮一手AC代码。
#include<bits/stdc++.h>
using namespace std;
vector<string> split(string s)
{
vector<string> ans;
for(int i=0;i<s.size();){
string atom;
if(s[i]>='A'&&s[i]<='Z'){
atom+=s[i];
++i;
while(i<s.size()&&(s[i]<'A'||s[i]>'Z')){
atom+=s[i];
++i;
}
ans.push_back(atom);
atom="";
}
}
return ans;
}
int main()
{
string str,ans,tmp;
getline(cin,str);
for(int i=0;i<str.size();++i){
if(str[i]!=' ')tmp+=str[i];
}
str=tmp;
for(int i=0;i<str.size();){
vector<string> atoms;
if(str[i]=='('){
++i;
string tmp;
while(str[i]!=')'){//get the whole molecule in brankets
tmp+=str[i++];
}
++i;
atoms=split(tmp);
}
string atom;
if(str[i]>='A'&&str[i]<='Z'){
atom+=str[i];
++i;
while(str[i]>='a'&&str[i]<='z'){
atom+=str[i];
++i;
}
}
int number=1;//default number of atom is 1
if(str[i]=='{'){
++i;
number=0;
while(str[i]!='}'){
number=number*10+str[i]-'0';
++i;
}
++i;
}
if(atoms.size()){
for(auto str:atoms){
for(int i=0;i<number;++i){
ans+=str;
}
}
atoms.clear();
}
if(atom.size()){
for(int i=0;i<number;++i){
ans+=atom;
}
}
}
cout<<ans;
return 0;
}
其实这题是我很久以前开始补得了,但是奈何大模拟题没有固定的算法,始终没有思路。
今天(2020年5月11日19:08),我正在准备这一周的期末考试。我被老师纯粹念PPT的视频搞得有些烦了,百无聊赖中突然想再次挑战这题。
首先还是看了一下官方题解,“按照规则处理字符串即可,考验码力”。这句话简直就是废话。
然后看了一下标程,完全没有思路。于是看了看其他过题的大佬是怎么写的。
突然,我灵感迸发。我先处理了一下圆括号里的情形。可以先将圆括号内的字符串全部分词成vector<string>
类型的变量。然后再处理花括号里面的数字。因为右圆括号后面一定是左花括号,所以我就在后面解析出次数$number$。最后遍历vector<string>
类型变量里所有的元素,赋值到字符串$ans$里$number$次。调试一下,形如(sss){aaa}
的情况解决了。
下一步将解决游离在括号外面的原子。这里我还在纠结要不要把连续的游离字符串全部读入,然后调用split
函数。后来意识到存在形如A{aaa}
的情形,改成了读一个处理一个,受到大佬代码的启发,我把$number$默认值设为$1$,因为如果原子后面没有花括号,就输出一次。
接下来就是最让人恶心激动人心的debug环节。一开始,我不知道它为什么会超时。后来发现,我又傻逼了。我在循环的开头写了一段代码:
if(s[i]==' ')continue;
我写的时候懵得太远了,以为最外层for循环会自动步进,最后知道真相的我眼泪掉下来。最后,预处理掉空格,提交,AC!
总用时约$80$分钟。
经验教训
1.审题。
2.首先要列提纲,分出各个模块。
3.最好每写一个模块调试一个模块,确保模块正确运行才写下一个。
其他没有了……
感受
来说说感受写写散文。
出题人说,他用$20$分钟写完了标程。果然出题和做题不是同样的感受呢。
@cht 大佬你在哪儿,我AC了。
orz
orz
我来了,蒟蒻的我来了。。。。。
# tql
# orz
# %%%%%%%%%%%%%%%%%%%
原来是你orzzz
原来是你TQLLL
O,Orz