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





發佈了156 篇原創文章 · 獲贊 56 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章