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.
InputThe 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.
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.
(((#)((#)
1 2
()((#((#(#()
2 2 1
#
-1
(#)
-1
|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]);
}