Treasure CodeForces - 494A 思路题

Malek has recently found a treasure map. While he was looking for a treasure he found a locked door. There was a string s written on the door consisting of characters '(', ')' and '#'. Below there was a manual on how to open the door. After spending a long time Malek managed to decode the manual and found out that the goal is to replace each '#' with one or more ')' characters so that the final string becomes beautiful.

Below there was also written that a string is called beautiful if for each i (1 ≤ i ≤ |s|) there are no more ')' characters than '(' characters among the first i characters of s and also the total number of '(' characters is equal to the total number of ')' characters.

Help Malek open the door by telling him for each '#' character how many ')' characters he must replace it with.

Input

The first line of the input contains a string s (1 ≤ |s| ≤ 105). Each character of this string is one of the characters '(', ')' or '#'. It is guaranteed that s contains at least one '#' character.

Output

If there is no way of replacing '#' characters which leads to a beautiful string print  - 1. Otherwise for each character '#' print a separate line containing a positive integer, the number of ')' characters this character must be replaced with.

If there are several possible answers, you may output any of them.

Example
Input
(((#)((#)
Output
1
2
Input
()((#((#(#()
Output
2
2
1
Input
#
Output
-1
Input
(#)
Output
-1
Note

|s| denotes the length of the string s.

题意:‘#’可以变成  若干个‘)’(至少一个)使得所有的左括号都有右括号和他匹配。如果可以,按顺序输出每个‘#’所代替的右括号的数量。

思路: 举个栗子 ( ) ( # ( )   先匹配右括号,每一个右括号要有一个左括号和他匹配,那么这个左括号该选哪里的呢?
因为#只能匹配他左边的左括号,那么#号右边的左括号就只能由右括号匹配,所以每个右括号优先匹配他左边第一个左括号

将所有的右括号匹配成功后,就只剩下右括号和#了,每个#必须先有一个左括号,然后再考虑剩下的左括号有没有必须要和这个#号匹配的。  举个栗子:(((#(#(((##    ,按顺序分为#1,#2....,和 (1, (2.....   先给#4一个(7,    (6的话不是必须给#4的,那就不给了。   先给#3一个(6,   那么(5必须给#3,不然就没法给剩余的#1,#2了。  所以先给每个#分一个(,剩下的(有必须给的才给,不然就留下来。,一直这样匹配,直到结束为止。

代码:

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
#define inf 0x3f3f3f3f
#define N 200500
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a));
using namespace std;
char s[101000];
int st[101000],str[101000];//st[]为存(的下标的栈,str[]存#下标的栈
int ans[101000];//存答案的数组
int main()
{
    int tot=0,totr=0;//两个栈的头
    scanf("%s",s);
    int ls=strlen(s);
    for(int i=0; i<ls; i++)
    {
        if(s[i]=='#') str[++totr]=i;//将#放入str[]中,存的是下标
        else  if(s[i]=='(')
        {
            st[++tot]=i;//将(放入st[]中
        }
        else
        {//如果是),则给他匹配一个在他左边的最近的(。
            if(!tot)//没有输出-1
            {
                printf("-1\n");
                return 0;
            }
            tot--;//有则匹配
        }
    }
    int w=0,sum=0;//sum表示给#匹配的(的个数, w为第几个#
    while(totr)//有#的话,倒着匹配#号
    {
        sum=0;//初始化
        if(!tot||st[tot]>str[totr])//没有(了,或者是说还有(在#的右边,这样就无法完成匹配了
        {
            printf("-1\n");
            return 0;
        }
        tot--;//有(就先分一个,
        sum++;//个数++
        while(tot&&st[tot]>=str[totr-1])//然后判断剩下的有没有必须分给这个#的
        {//有(,并且这些(的坐标是大于下一个#的,也就是说这些(无法跟剩余#匹配,而只能与此#匹配
            sum++;//st[tot]>=str[totr-1]这里的>=中的=号是有必要的,当栈里只剩一个#是,totr-1是0了,str[0]是没存东西的,值为0,剩下的所有的括号的坐标都是大于0的,所以可以将剩余的所有(都匹配完成
            tot--;//有则匹配
        }
        ans[w++]=sum;//匹配完成
        totr--;//此#删掉
    }
    for(int i=w-1; i>=0; i--)//倒着输出
        printf("%d\n",ans[i]);
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值