zoukankan      html  css  js  c++  java
  • uoj problem 31 猪猪侠再战括号序列

    题目大意:

    给定一个长度为2n的括号序列.定义一个关于区间[l,r]的翻转操作为位置平移对调.
    即翻转")))()("可以得到"()()))(("
    用不超过n次翻转操作使给出的序列变为合法的序列.(n leq 100000)

    题解:

    因为给出了n次翻转操作的机会。
    如果我们考虑构造出"(((((())))))"的合法的括号序列
    很容易得到这样的策略:

    • 从左到右依次检查左半部分,如果出现了右括号,就向右找到第一个出现的左括号然后交换两括号,使当前位置变为左括号。

    这样的话算上翻转序列的复杂度一共是(O(n^3))
    但是仔细思考可以发现,我们每次的翻转序列操作只交换了左右两端的括号。
    因为右端点是从左端点开始向右寻找找到的第一个左括号。所以中间的括号全部都是右括号。
    区间翻转不会对其造成任何影响
    交换两端点即可,复杂度降到(O(n^2))
    我们又发觉右端点是单调的.
    复杂度降到(O(n))

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
    	x=0;char ch;bool flag = false;
    	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    #define rg register int
    #define rep(i,a,b) for(rg i=(a);i<=(b);++i)
    #define per(i,a,b) for(rg i=(a);i>=(b);--i)
    const int maxn = 200010;
    char s[maxn];
    struct Node{
    	int l,r;
    	Node(){}
    	Node(const int &a,const int &b){
    		l = a;r = b;
    	}
    }sta[maxn];
    int top;
    int main(){
    	scanf("%s",s+1);
    	int n = strlen(s+1),j = 0;
    	rep(i,1,n){
    		if(s[i] == ')'){
    			j = max(i+1,j);
    			for(;j<=n;++j) if(s[j] == '('){
    				sta[++top] = Node(i,j);
    				swap(s[i],s[j]);
    				break;
    			}
    		}
    	}
    	printf("%d
    ",top);
    	rep(i,1,top){
    		printf("%d %d
    ",sta[i].l,sta[i].r);
    	}
    	return 0;
    }
    
  • 相关阅读:
    功能强大的T4文本模版
    C#中.snk文件的作用
    ASP.NET MVC中实现多个按钮提交的几种方法
    asp.net mvc强大的分页控件MvcPager
    设计模式—观察者模式
    Http响应码

    编码习惯
    vim 快捷键 转
    makefilevvhttp://www.tudou.com/programs/view/e3Z8RbxFIZE/
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6866890.html
Copyright © 2011-2022 走看看