hdu5479

题目:点击打开链接


题解:

不能用栈,会爆栈

全部转化成不匹配,要不就是全化为((((或))))或))))((((这三种情况必居其一

思路是从左到右和从右到左各扫描一次记录 ( 和 ) 的到每个位置的数量,

遍历一下将每个位置的左方全转置成 ) 和右方全转置成 ( 需要的次数和,凑成))))((((的情况,求最小的那个,这么算发现有一个转置是不必要的,注意减一

根据下面这个样例会比较容易理解

下面这个是的i和l[i]和r[i]

i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

l[i] 0 0 0 1 1 2 3 3 3 3 4 5 6 6 7 8 9

r[i] 8 7 6 5 5 4 4 4 3 2 1 1 1 1 0 0 0

结果是当i=11时最小,为4

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>

using namespace std;

#define INF 0x3f3f3f3f
char s[1010];
int l[1010],r[1010];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%s",s);
        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));
        int len=strlen(s);
        for(int i=len-1;i>=0;i--)
        {
            if(i==len-1)
                r[i]=(s[i]==')');//统计)的个数
            else
                r[i]=r[i+1]+(s[i]==')');
        }
        for(int i=0;i<len;i++)
        {
            if(i==0)
                l[i]=(s[i]=='(');//统计(的个数
            else
                l[i]=l[i-1]+(s[i]=='(');
        }
        int ans=INF;//很大
        for(int i=0;i<len;i++)
            ans=min(ans,l[i]+r[i]-1);
        printf("%d\n",ans);
    }
    return 0;
}


害羞

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值