zoukankan      html  css  js  c++  java
  • UOJ#31 【UR #2】猪猪侠再战括号序列

    传送门http://uoj.ac/problem/31

    大家好我是来自百度贴吧的_叫我猪猪侠,英文名叫_CallMeGGBond。

    我不曾上过大学,但这不影响我对离散数学、复杂性分析等领域的兴趣;尤其是括号序列理论,一度令我沉浸其中,无法自拔。至于OI算法竞赛,我年轻时确有参加,虽仅获一枚铜牌,但我素性淡泊,毫不在意,毕竟那所谓FFT、仙人掌之类,只是些雕虫小技罢了,登不上大雅之堂的;只有括号序列才会真正激发我的研究热情。

    我曾天真地以为,凭借我的学识与才能,足可以在这世间安身立命;然而直到沦落街头后,我终才领悟现实的残酷。迫于生计,我只得转向道德与哲学的研究;但我与括号序列之间情愫依旧,难以剪断。

    理性的传播总是不顺的,研究的道路也是曲折的,但轻易放弃决不是我的风格;为了继续实现自己的理想,现在我向大家提出一道括号序列的超级大难题。

    有一个由 nn 个左括号 “(” 和 nn 个右括号 “)” 组成的序列。每次操作时可以选定两个数 l,rl,r,然后把第 ll 到第 rr 个括号的顺序翻转(括号的朝向保持不变)。例如将 “()((()(” 翻转第 33 到第 77 个括号后的结果为 “()()(((”。

    我希望使用不超过 nn 次操作,将这个序列变为一个合法的括号序列。

    众所周知,合法括号序列的定义如下:

    1. () 是合法括号序列;
    2. 如果 A 是合法括号序列,则 (A) 是合法括号序列;
    3. 如果 AB 是合法括号序列,则 AB 是合法括号序列。

    自从来到 UOJ 这个宝地,我的视野变得开阔了,也见识了更多富有人类智慧的人士。我相信各位一定能给我更加满意的答案!

    输入格式

    一行一个长度为 2n2n 的非空字符串表示初始序列。保证字符串只包含左括号和右括号,且左右括号的个数均为 nn。

    输出格式

    对于给出的字符串,输出调整成合法的括号序列的方案。如果不存在这样的方案输出一行一个整数 1−1。

    否则,第一行一个整数 mm 表示要进行 mm 次翻转操作。

    接下来 mm 行每行两个整数 l,rl,r 表示要翻转区间 [l,r][l,r] 内的括号顺序。翻转操作会按你输出的顺序执行。

    请保证 mnm≤n 以及 1lr2n1≤l≤r≤2n,否则会被判 0 分。

    如果有多组方案,输出任意一组即可。

    样例一

    input

    )))()(((
    
    

    output

    2
    1 6
    5 8
    
    

    explanation

    第一次操作后序列变为 “()()))((”。

    第二次操作后序列变为 “()()(())”。

    限制与约定

    测试点编号nn的规模
    1 n4n≤4
    2 n100n≤100
    3
    4
    5
    6 n100000n≤100000
    7
    8
    9
    10

    时间限制:1s1s

    空间限制:256MB

    扫描 构造 脑洞题

    显然最方便的结果是((()))的形式。

    维护双指针扫描,head指向第一个右括号,tail指向head后面的第一个左括号,每步将两个位置的括号交换。

    显然是 $ O(n) $的

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 char s[200010];
     6 int ans=0,L[100010],R[100010];
     7 int main(){
     8     int i;
     9     scanf("%s",s+1);
    10     int n=strlen(s+1);
    11     int hd=1;
    12     for(i=1;i<=n;i++){
    13         if(s[i]=='('){
    14             while(hd<i && s[hd]!=')')hd++;
    15             if(hd^i){
    16                 swap(s[hd],s[i]);
    17                 ans++;
    18                 L[ans]=hd;R[ans]=i;
    19             }
    20         }
    21     }
    22     printf("%d
    ",ans);
    23     for(i=1;i<=ans;i++){
    24         printf("%d %d
    ",L[i],R[i]);
    25     }
    26     return 0;
    27 }
  • 相关阅读:
    虚函数
    类的继承
    析构
    构造
    枚举类型
    c++中的静态类型 static
    c++中的类
    sizeof和strlen的区别
    剑指36 二叉搜索书与双向链表
    剑指35 复杂链表的复制
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/7061334.html
Copyright © 2011-2022 走看看