Codeforces——1101B_Accordion(贪心)

本题可谓是历经波折啊。这也是一道具有贪心思想的题,要尽可能多的裁剪选出最长的“Accordion”,仔细分析一下可知,由于一个“Accordion”是以“[:||||…|||:]”的形式出现的,左右必有一个反向括号,内部左右顶端必有一个冒号,冒号中间夹杂着若干 | (可以为0)。
因此,我们可以从给出的字符串s中,找出第一次出现 [ 和最后出现 ] 的位置,接着在 [ ] 之间找出分别与 [ 和 ] ***相隔最近的那两个 :***(加个黑,自己意会下),接下来,只需在两个:之间找出 | 的个数即可。
代码如下:

#include<cstdio>
#include<cstring>
using namespace std;
char s[500005];
int main()
{
int i,j,len;   // i , j 控制循坏,len测出字符串的长度
int start=0,place1=0,flag1=0,F1=0;   //start 记录首个"["的位置,place1记录最邻近"["的 :,F1,flag1,分别标记这两个位置是否已经找到
int end=0,place2=0,flag2=0,F2=0;  //end记录最后的"]"的位置,place2记录最邻近"]"的 :,F2,flag2,分别标记这两个位置是否已经找到
int sum=0; //记录最长 Accordion 的长度
scanf("%s",s);
len=strlen(s)-1;
for(i=0;i<=len;i++)  //从前往后找出第一个"["的位置
{
if(s[i]=='[')
{
start=i;sum++;F1=1;   //找到了,便进行相关的数据处理,就可以结束了
break;
}
}
for(j=len;j>i;j--)  //从最末尾开始搜索最后一个"]"的位置,只需在(i,len)之间搜索即可
{
if(s[j]==']')
{
end=j;sum++;F2=1;  //数据处理
break;  //结束循坏
}
}
if(F1&&F2)   //是否找到了"[""]",是就继续,否则就可以结束了
{
for(i=start+1;i<=end-1;i++) //从start的下一个位置开始搜索 :的位置
  {
  if(s[i]==':')
  {
  place1=i;flag1=1;sum++;  //数据处理
  break;
   } 
  } 
for(j=end-1;j>i;j--)  //从end前一个位置开始搜索 :的位置,在(i,end-1)之间搜索即可
{
if(s[j]==':')  
{
place2=j;flag2=1;sum++; //printf("%d\n",place2);   这是 dig bug
break;
}
  }
  if(flag1&&flag2)  //找到了,就继续,没找到,就可以结束了
  {
  for(i=place1+1;i<=place2-1;i++)  //在(place1+1,place2-1)之间找“|”
  {
  if(s[i]=='|') sum++;
}
printf("%d\n",sum);  //输出总长度
}
else printf("-1\n");
    //printf("%d %d %d start,flag1,place1\n%d %d %d end,flag2,place2\n%d %d\n",start,flag1,place1,end,flag2,place2,cnt1,cnt2);   dig bug
}
else printf("-1\n");
return 0;
}

不难发现,该算法的时间复杂度是O(n+n),测s长度加查找,在n<=500000的数据里还是挺可观的。主要考码代码能力,而且分析的时候一定要细心,比如,加黑字的那些,如果一开始就想得深入一点,就不必花这么久时间了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值