标签:CF1101B 冒号 下标 Accordion int 题解 括号 flag 要点
PART 01:思路
我们知道最后的字符串一定是一个左右两边为括号的串,所以先找一波括号。
- 第一步,找左右括号。
接着在两个括号之间找出两个冒号,所以还要存下左右括号的下标。
- 第一步,找左右括号并存下下标。
- 第二步,找左右冒号。
最后在两个冒号之间找 \(|\) 字符,所以还要存下冒号的下标。
- 第一步,找左右括号并存下下标。
- 第二步,在左右括号之间找左右冒号并存下下标(这里可以搞一搞资源重复利用)。
- 第三步,找左右冒号之间的 \(|\) 符号,并记录有多少个 \(|\) ,最终答案则是4加上 \(|\) 的个数。
PART 02:算法
2.1:初始化+找左右括号
int length=0;
string a;
cin>>a;
length=a.length();
int left=-1;
int right=-1;
for(int i=0;i<length;i++){
if(a[i]=='['&&left==-1){
left=i;
}
if(a[i]==']'){
right=i;
}
}
要点1:之所以要使用 length 变量来表示字符串 a 的长度,是为了之后使用方便,不必反复用函数读取,好习惯。
要点2:由于字符串下标从0开始,变量必须先赋值为负数,-1 较为方便。
要点3A:为了避免存在多个左括号,一定要保留最先出现的左括号下标!
要点3B:右括号为了找出最后出现的一个,遇到一个变一个,因为 i 在逐渐增大。
2.2:第一处合法性判断
if(left==-1||right==-1){
cout<<"-1"<<endl;
return 0;
}
显然,如果 left 没有变化(即没有左括号)或者 right 没有变化(即没有右括号),这个串是非法的。
2.3:初始化+找左右冒号
int l=-1;
int r=-1;
int flag=0;
for(int i=left+1;i<right;i++){
if(a[i]==':'&&flag==1){
r=i;
}
if(a[i]==':'&&flag==0){
flag=1;
l=i;
}
要点1:flag 的作用在于确认是否是第一个冒号,如果是,执行第二个 if 中的内容(确定左下标并改变 flag);否则执行第一个 if 中的内容(确定右下标)。
要点2:利用 flag 我们也实现了找出最小下标的左冒号与最大下标的右冒号,使得串最长化。
要点3:观察循环初始化与条件,发现我们是在左右括号内进行搜找(所以要记下两个括号的下标)。
要点4:第二个 if 必须放在第一个 if 的后面,否则遇到第一个冒号时,改变了 flag 的值,导致另外一个 if 不恰当开始。
2.4:第二处合法性判断
if(l==-1||r==-1){
cout<<"-1"<<endl;
return 0;
}
显然的,当找不出左冒号(变量 l 无变化)或右冒号(变量 r 无变化)时,该串不合法。
2.5:找 \(|\) 符号
int cnt=0;
for(int i=l+1;i<r;i++){
if(a[i]=='|'){
cnt++;
}
}
用 cnt 记录两个冒号之中 \(|\) 符号的个数,循环区间为两个冒号之间。
程序最后,直接输出 cnt+4 即可。
PART 03:AC 代码
本题中各部分已经讲得很透彻,不给出完整代码。
标签:CF1101B,冒号,下标,Accordion,int,题解,括号,flag,要点 来源: https://www.cnblogs.com/lemonniforever/p/solution-cf1101b.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。