HDU 4915

贪心,left_min[i]记录在保证1~i合法的情况下1~i最少的‘(’个数,left_max[i]记录在保证1~i合法的情况下1~i最多的‘(’个数,right_min[i]记录在保证(i+1)~n合法的情况下(i+1)~n最少的‘(’个数,right_max[i]记录在保证(i+1)~n合法的情况下(i+1)~n最多的‘(’个数。因为左括号是向右匹配的,所以向右贪心,而右括号是向左匹配的,所以向左贪心。
在贪心的过程中,检查是否会出现非法情况,min[i]>max[i]。出现则无解,否则有解。
多解的情况判断需要判断区间[left_min[i],left_max[i]]与[right_min[i],right_max[i]]的区间交是否长度大于1。只要存在一处区间交长度大于1,那么说明在这一处可以有多种情况,即存在多解。

#include<bits/stdc++.h>
#define rep(a,b,c) for(int a=b;a<c;a++)
#define LL long long
using namespace std;
const int maxn=1e6+5;
const int Inf=1e9+7;
const int mod=3;
char s[maxn];
int n;
int left_min[maxn], left_max[maxn];
int right_min[maxn], right_max[maxn];
int main()
{   int T;

    while(~scanf("%s",s+1)){
        n=strlen(s+1);
        if(n%2) {puts("None");continue;}
        int no_ans=0;
        left_min[0]=left_max[0]=0;
        for(int i=1;i<=n;i++){
            if(s[i]=='('){
                left_min[i]=left_min[i-1]+1;
                left_max[i]=left_max[i-1]+1;
            }else if(s[i]==')'){
                if(!left_min[i-1]) left_min[i]=1;//from left,we can let left brackets more than rights
                else left_min[i]=left_min[i-1]-1;
                left_max[i]=left_max[i-1]-1;
            }else{
                if(!left_min[i-1]) left_min[i]=1;
                else left_min[i]=left_min[i-1]-1;
                left_max[i]=left_max[i-1]+1;
            }
            if(left_min[i]>left_max[i]) no_ans=1;
        }
        if(no_ans){puts("None");continue;}

        right_min[n]=right_max[n]=0;
        for(int i=n;i>0;i--){
            if(s[i]=='('){
                if(!right_min[i]) right_min[i-1]=1;
                else right_min[i-1]=right_min[i]-1;
                right_max[i-1]=right_max[i]-1;
            }else if(s[i]==')'){
                right_min[i-1]=right_min[i]+1;
                right_max[i-1]=right_max[i]+1;
            }else{
                if(!right_min[i]) right_min[i-1]=1;
                else right_min[i-1]=right_min[i]-1;
                right_max[i-1]=right_max[i]+1;
            }
            if(right_min[i]>right_max[i]) no_ans=1;
        }
        if(no_ans) {puts("None");continue;}

        int multi_ans=0;
        for(int i=1;i<=n;i++){
            int l=max(left_min[i], right_min[i]);
            int r=min(left_max[i], right_max[i]);
            if(l<r) multi_ans=1;
        }
        if(multi_ans) puts("Many");
        else puts("Unique");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值