HDU4915:Parenthese sequence(贪心)

Problem Description

bobo found an ancient string. The string contains only three charaters -- "(", ")" and "?".

bobo would like to replace each "?" with "(" or ")" so that the string is valid (defined as follows). Check if the way of replacement can be uniquely determined.

Note:

An empty string is valid.

If S is valid, (S) is valid.

If U,V are valid, UV is valid.

Input

The input consists of several tests. For each tests:

A string s1s2…sn (1≤n≤106).

Output

For each tests:

If there is unique valid string, print "Unique". If there are no valid strings at all, print "None". Otherwise, print "Many".

Sample Input

??
????
(??

Sample Output

Unique
Many
None

从前扫一遍,记录最大和最小的可能的左括号的值

如果左括号的大小小于右括号的大小,则必定不行

从后扫一遍,同样记录最大和最小的可能的左括号的值

如果右括号的大小小于左括号的大小,则必定不行

然后找最小值中的最大值,和最大值中的最小值

如果前者大于后者,则不行,如果后者大于前者则有多重解,如果相等则为唯一解

嗯,发现我代码越来越飘逸了,有木有
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define mem(a,b) memset(a,0,sizeof(a))
#define L 1000005
#define up(i,x,y) for(i = x;i<=y;i++)
#define down(i,x,y) for(i = x;i>=y;i--)
#define bre(x,y) if(x){flag=y;break;}
#define con(x,y) if(x){ans(y);continue;}
char s[L];
int a[L][2],b[L][2],len,flag;

void ans(int i)
{
    if(i==1) printf("Unique\n");
    else if(i==2) printf("Many\n");
    else printf("None\n");
}

int main()
{
    int i,j;
    while(~scanf("%s",s+1))
    {
        len = strlen(s+1);
        con((len&1),0)
        mem(a,0);
        mem(b,0);
        flag = 1;
        up(i,1,len)
        {
            if(s[i]=='(')
                a[i][0]=a[i-1][0]+1,a[i][1]=a[i-1][1]+1;
            else if(s[i]==')')
            {
                if(!a[i-1][0])
                    a[i][0]=1;
                else
                    a[i][0]=a[i-1][0]-1;
                a[i][1]=a[i-1][1]-1;
            }
            else if(s[i]=='?')
            {
                if(!a[i-1][0]) a[i][0]=1;
                else
                    a[i][0]=a[i-1][0]-1;
                a[i][1]=a[i-1][1]+1;
            }
            bre((a[i][0]>a[i][1]),0)
        }
        con((!flag),0)
        down(i,len,1)
        {
            if(s[i]==')')
                b[i-1][0]=b[i][0]+1,b[i-1][1]=b[i][1]+1;
            else if(s[i]=='(')
            {
                if(!b[i][0])
                    b[i-1][0]=1;
                else
                    b[i-1][0]=b[i][0]-1;
                b[i-1][1]=b[i][1]-1;
            }
            else if(s[i]=='?')
            {
                if(!b[i][0]) b[i-1][0]=1;
                else
                    b[i-1][0]=b[i][0]-1;
                b[i-1][1]=b[i][1]+1;
            }
            bre((b[i][0]>b[i][1]),0)
        }
        con((!flag),0)
        int l,r;
        flag = 1;
        up(i,1,len)
        {
            l = max(a[i][0],b[i][0]);
            r = min(a[i][1],b[i][1]);
            bre((l>r),0)
            bre((l<r),2)
        }
        con((flag==0),0);
        con((flag==1),1);
        con((flag==2),2);
    }

    return 0;
}

HDU4915:Parenthese sequence(贪心)

时间: 2024-08-08 06:58:09

HDU4915:Parenthese sequence(贪心)的相关文章

hdu4915 Parenthese sequence 贪心O(n)解法

hdu4915 Parenthese sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 82    Accepted Submission(s): 25 Problem Description bobo found an ancient string. The string contains only three c

hdu 4915 Parenthese sequence (贪心+模拟)

题目大意: 一个序列中有左括号和右括号,还有问号,问号可以任意转换成左右括号. 问这个序列有多少种情况的转变使得这个序列变成合法的括号匹配序列. 思路分析: 首先我们分析一下,如何使得一个序列是合法的括号匹配序列. 我们很容易想到的是用栈模拟匹配过程. 当遇到左括号就进栈,当遇到右括号就让栈顶的左括号出栈. 那么在模拟的过程中,造成这个序列的不合法的原因只有当右括号来的时候,此时的栈已经为空. 这里补充一句,一旦一个序列给定,那么这里面的问号有多少变成左括号,多少变成右括号,是一定的. 看完以上

HDU5014Number Sequence(贪心)

HDU5014Number Sequence(贪心) 题目链接 题目大意: 给出n,然后给出一个数字串,长度为n + 1, 范围在[0, n - 1].然后要求你找出另外一个序列B,满足上述的要求,而且使得t = A0^B0 + Ai + 1 ^ Bi + 1 + ... + An ^ Bn 最大. 解题思路: 对于一个数字进行异或,要求结果最大的话,那么取这个数字的二进制互补数字是最好的情况,而且能够发现每次找到一个数字和相应的互补的数字都会是一段区间.就这样一段一段区间的去寻找每一个点相应的

HDU 5014 Number Sequence 贪心 2014 ACM/ICPC Asia Regional Xi&#39;an Online

尽可能凑2^x-1 #include <cstdio> #include <cstring> const int N = 100005; int a[N], p[N]; int init(int x) { int cnt = 0; while(x > 1) { x /= 2; cnt ++; } return cnt + 1; } int main() { int n; while(~scanf("%d", &n)){ for(int i = 0;

HDU 4915 Parenthese sequence

HDU 4915 Parenthese sequence 题目链接 题意:给定一个有?的左右括号串,?能替代为'('或')',问括号匹配是否唯一或多种或不可能 思路:先从右往左扫一边,维护一个up, down表示当前位置右边右括号剩余个数的上限和下限,如果维护完后起始位置的下限为0,那么就是可以的,因为为0就代表没有多余的右括号.然后在从左往右扫一遍,和上面一样的处理,只是遇到每个问号的位置时,试一下左括号和右括号,如果都满足,表示这个位置能放左右括号,是多种可能,如果所有?都只有唯一的方法,那

hdu 4915 Parenthese sequence(高效)

题目链接:hdu 4915 Parenthese sequence 题目大意:给定一个序列,由(,),?组成?可以表示(或者),问说有一种.多种或者不存在匹配. 解题思路:从左向右,从右向左,分别维护左括号和右括号可能的情况,区间上下界.如果过程中出现矛盾,则为None,否则要判断唯一解还是多解.枚举每个问号的位置,假设该问号可为左右括号,则有多解. #include <cstdio> #include <cstring> #include <algorithm> us

HDU 4915 Parenthese sequence(瞎搞题)

从左向右扫一遍左括号的最大值,与最小值. 从右向左扫一遍右括号的最大值,与最小值. 比较最大值中的最小数与最小中的最大数看能否有交集,0个,1个或者多个. Parenthese sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 301    Accepted Submission(s): 129 Problem De

HDU 4915 多校5 Parenthese sequence

比赛的时候想了一个自认为对的方法,WA到死,然后还一直敲下去,一直到晚上才想到反例 找是否存在解比较好找,这种左右括号序列,把(当成1,把)当成-1,然后从前往后扫,+1或者-1 遇到?就当初(,然后如果扫到最后 中间没有出现负数说明左括号没问题 然后同样的方法从后往前扫,判断右括号那里是不是有问题即可.都没问题就有解,否则无解 当然应该要先判断下序列长度是不是偶数,奇数肯定是无解 至于为什么要像之前的处理即可判断有无解,首先只有正好走完的时候 和值为0才是真正合法(因为这个时候左右括号都对应了

HDU 4915 Parenthese sequence _(:зゝ∠)_ 呵呵

呵呵不是我做的 #include <cstdio> #include <cstring> #include <algorithm> const int N = 1000000 + 10; char s[N]; int d[N], num[N]; int main() { while (~scanf("%s", s)) { memset(num, 0, sizeof num); int len = strlen(s); int f = 1, v = 0