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

Codeforces Round #712 (Div. 2) C

时间:2021-04-06 14:45:19      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:理解   its   mes   研究   ios   sig   技术   alt   序列   

题目链接
https://codeforces.ml/contest/1504/problem/C
题目截图
技术图片
题目大致描述
给定一个01串,判断是否能构造出两个平衡的括号序列ans1和ans2,若能给定其中一种解,构造需满足以下规则:
对于01串中元素为0的位置i,ans1[i] != ans2[i]
对于01串中元素为1的位置i,ans1[i] == ans2[i]
题解
这题是是我在调B调到自闭的时候切的题目。。。比赛时到知道写假了。。。贪心部分贪错了
赛后我看了一下打算暴力搜索。。果真TLE了
于是研究了下出题人的思路,以下便是对出题人的理解(尽管他出的题目我掉了近两百分。。不过该出题人确实有水平。。
首先统计01串中0的数目,若0的数目为奇数显然无法构造,原因如下:
对于01串中的1可以贡献ans1和ans2偶数个‘(‘,对于01串中的0可以贡献ans1和ans2奇数个‘(‘,由于ans1和ans2均为平衡括号序列,故‘(‘个数 == ‘)‘个数,又有n是偶数,故‘(‘数目是偶数,那么0的数目是偶数
其次对于平衡括号序列,首位必须分别为‘(‘和‘)‘因此01串首位必须同时为1
然后大胆猜想,上面的必要条件是不是也是充分条件呢?
事实上出题人提供了一个比较巧妙的构造方法,如下
对于01串中的1显然也是偶数,因此对于前一半1 ans1[i] = ans2[i] = ‘(‘,对于后一半1 ans1[i] = ans2[i] = ‘)‘,此时1对应的括号是成对存在且匹配
对于01串中的0可以交替赋值‘(‘以及‘)‘,可以证明此时ans1和ans2均为平衡括号序列
代码如下

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define IOS std::ios_base::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
using namespace std;
const int maxn = 2e5 + 50;

int t;
int n;
char s[maxn];
int cnt;
char ans1[maxn], ans2[maxn];

signed main() {
    IOS
    cin >> t;
    while(t--) {
        cin >> n;
        cin >> (s + 1);
        cnt = 0;
        for(int i = 1;i <= n;++i) {
            if(s[i] == ‘0‘) { ++cnt; }
        }
        if(cnt % 2 == 1 || s[1] == ‘0‘ || s[n] == ‘0‘) {
            cout << "NO\n";
            continue;
        }
        int k = 0;
        for(int i = 1;i <= n;++i) {
            if(s[i] == ‘1‘) {
                if(2 * k < n - cnt) {
                    ans1[i] = ans2[i] = ‘(‘;
                    k++;
                } else {
                    ans1[i] = ans2[i] = ‘)‘;
                    k++;
                }
            } 
        }        
        bool flag = true;
        for(int i = 1;i <= n;++i) {
            if(s[i] == ‘0‘) {
                if(flag) {
                    ans1[i] = ‘(‘;
                    ans2[i] = ‘)‘;
                    flag = !flag;
                } else {
                    ans1[i] = ‘)‘;
                    ans2[i] = ‘(‘;
                    flag = !flag;
                }
            }
        }
        ans1[n+1] = ans2[n+1] = 0;
        cout << "YES\n";
        cout << (ans1 + 1) << ‘\n‘;
        cout << (ans2 + 1) << ‘\n‘;
    }
    return 0;
}

Codeforces Round #712 (Div. 2) C

标签:理解   its   mes   研究   ios   sig   技术   alt   序列   

原文地址:https://www.cnblogs.com/mfsyflt/p/14616545.html

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