码迷,mamicode.com
首页 > 其他好文 > 详细

CF1153C. Serval and Parenthesis Sequence

时间:2019-05-13 22:48:40      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:说明   char   name   pre   并且   fine   else   scanf   就是   

题意

给一个包含‘(‘,‘)‘,‘?‘的串,需要在‘?‘处填‘(‘或‘)‘,使其满足

  • 每个严格前缀(严格前缀 指不是整个串的所有前缀)不是可匹配的括号序列
  • 整个串是可匹配的括号序列

无法构造输出:(

题解

其实就是构造一个首尾对应的括号序列。

那么把第一个和最后一个排除了,把中间的那些构造成一个合法的括号序列就行了。

至于怎么构造,使用贪心:

  • 首先先将能匹配的‘(‘和‘)‘给匹配了,并且尽量相近的匹配。
  • 然后用‘?‘位来补‘(‘和‘)‘剩下的。
  • 最后剩余的‘?‘位自己匹配自己。

最后判定一下这样构造出来的括号序列合不合法(如果不合法就说明构造不出来)即可。

好像写复杂了...看了一下别人的构造方法都很简短...

#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int N = 300010;

int n, top;
char s[N];
bool vis[N];
int id[N];

int main() {
    scanf("%d", &n);
    scanf("%s", s + 1);
    if(s[1] == ')' || s[n] == '(') return puts(":("), 0;
    s[1] = '('; s[n] = ')';

    int cur = 1, tot = 0;
    for(int i = 2; i < n; ++i) if(s[i] == ')') id[++tot] = i;
    for(int i = 2; i < n; ++i) {
        if(s[i] == '(') {
            if(cur <= tot) {
                vis[id[cur]] = 1;
                vis[i] = 1;
                ++cur;
            }
        } 
        if(id[cur] == i) ++cur;
    }
    
    cur = n - 1;
    for(int i = 2; i < n; ++i) {
        if(s[i] == '(' && !vis[i]) {
            while(cur > 1 && ( s[cur] != '?' || (s[cur] == '?' && vis[cur]) ) ) 
                --cur;
            if(s[cur] == '?' && !vis[cur]) 
                vis[cur] = 1, s[cur] = ')', vis[i] = 1;
        } 
    }
    cur = 2;
    for(int i = n - 1; i > 1; --i) {
        if(s[i] == ')' && !vis[i]) {
            while(cur < n && ( s[cur] != '?' || (s[cur] == '?' && vis[cur] ) ) ) ++cur;
            if(s[cur] == '?' && !vis[cur]) vis[cur] = 1, s[cur] = '(', vis[i] = 1;
        }
    }
    
    bool flag = 0;
    top = 0;
    for(int i = 2; i < n; ++i) {
        if(s[i] == '?' && !vis[i]) {
            s[i] = flag ? ')' : '(';
            flag ^= 1;
        }
    }
    
    for(int i = 1; i <= n; ++i) {
        if(s[i] == '(') ++top;
        else --top;
        if(top <= 0 && i != n) return puts(":("), 0;
    }
    if(top != 0) return puts(":("), 0;
    puts(s + 1);
}

CF1153C. Serval and Parenthesis Sequence

标签:说明   char   name   pre   并且   fine   else   scanf   就是   

原文地址:https://www.cnblogs.com/henry-1202/p/10859410.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!