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]);
}