[CSP-S模拟测试]:括号密码(贪心)
题目描述
在“无限神机”的核心上,有一个奇怪的括号密码,密码初始已经有一个括号序列,有$n$个限制条件,每个限制条件描述为$l_i$和$r_i$,表示区间$[l_i,r_i]$的括号序列必须合法。调整密码只有一种方式:交换括号序列的任意两个字符。求使得密码满足所有条件最少的交换次数。
括号序列合法定义为:
$1.$空串$""$是一个合法的括号序列
$2.$如果$"X"$和$"Y"$是合法的括号序列,则$"XY"$(连接$X$和$Y$)是合法的括号序列
$3.$如果$"X"$是合法的括号序列,则$"(X)"$是合法的括号序列
$4.$每个合法的括号序列均可由上述规则推导出。
例如,$"","()","()()()","(()())"$和$"(((())))"$都是合法的括号序列。显然,只有长度为偶数的才有可能是合法的括号序列
输入格式
第一行有一个字符串$s$,表示原括号序列
第二行一个整数$n$,表示限制条件的个数
第三行$n$个整数,表示$l_i$
第四行$n$个整数,表示$r_i$
输出格式
输出一个整数,表示最少交换次数,无解输出$-1$
样例
样例输入1:
)(
4
0 0 0 0
1 1 1 1
样例输出1:
1
样例输入2:
(((())
2
0 2
1 3
样例输出2:
2
数据范围与提示
样例$1$解释:
$L$和$R$描述了$4$个相同的条件,即要求从$s[0]$到$s[1]$是正确的括号序列。只需要做$1$次交换$s[0]$和$s[1]$就可以得到正确的括号序列。
样例$2$解释:
需要交换$(s[1],s[4])$和交换$(s[3],s[5])$
数据范围:
每个测试点的数据规模及特点如下表所示。设字符串长度为$|S|$
题解
先来考虑区间不重叠的情况:
对每个区间,统计区间前缀和,设前缀和最小值为$w$,区间总和为$a$($a$必须为偶数,否则无解) 使$a$变为$0$,需要从区间外引进括号,只计算引进’)‘数量,最后判断如果所有条件区间的’)‘不够,再从外面进口’)’ 若$a>0$,则需引进$\frac{a}{2}$个’)’,使得$a$变为$0$,每次贪心选择最右边的’(‘修改,$w$不改变(将这些进口操作记录到答案) 若$a<0$,需将这里的’)’出口到其它区间,贪心选择最左边的’)’修改,$w$会增加$|a|$(但这些修改不计算入答案,我们只计算引入’(‘数量) 最后加上$\frac{w}{2}$次区间内部操作,使得前缀和不存在负数。
再来考虑会出现重叠,但是无嵌套:
不妨设这两个区间分别为$l_i\sim r_i$和$l_j\sim r_j$,且$l_j<r_i$。
有一个很简单的解决方法,可以直接将这两个区间拆成$l_i\sim l_j-1,l_j\sim r_i,r_i+1\sim r_j$即可。
如果区间有嵌套仍可以按这种方法解决,代码实现细节比较多。
时间复杂度:$\Theta(n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
struct rec{int l,r;}e[100001];
int n;
int cnt=1,suml,sumr,resl,resr;
char ch[100001];
int l[100001],r[100001];
vector<int> vec[100001];
vector<char> s[100001];
map<vector<int>,int>mp;
int ans;
void work(int x)
{
ans+=(min(l[x],r[x])+1)>>1;
int mid=(l[x]-r[x])>>1;
if(mid<0)
{
mid=-mid;
int flag=min(mid,resl);
mid-=flag;
resl-=flag;
ans+=flag;
resr+=mid;
}
else
{
int flag=min(mid,resr);
mid-=flag;
resr-=flag;
ans+=flag;
resl+=mid;
}
}
int main()
{
scanf("%s%d",ch+1,&n);
int len=strlen(ch+1);
for(int i=1;i<=n;i++){scanf("%d",&e[i].l);e[i].l++;}
for(int i=1;i<=n;i++)
{
scanf("%d",&e[i].r);
e[i].r++;
for(int j=e[i].l;j<=e[i].r;j++)vec[j].push_back(i);
}
mp[vec[0]]=1;
for(int i=1;i<=len;i++)
{
if(!mp[vec[i]])mp[vec[i]]=++cnt;
s[mp[vec[i]]].push_back(ch[i]);
}
for(int i=0;i<s[1].size();i++)
if(s[1][i]=='(')suml++;
else sumr++;
for(int i=2,L,R;i<=cnt;i++)
{
L=R=0;
for(int j=0;j<s[i].size();j++)
{
if(s[i][j]=='(')L++;
else R++;
l[i]=max(l[i],R-L);
}
L=R=0;
for(int j=s[i].size()-1;j>=0;j--)
{
if(s[i][j]=='(')L++;
else R++;
r[i]=max(r[i],L-R);
}
if(abs(L-R)&1){puts("-1");return 0;}
}
for(int i=2;i<=cnt;i++)work(i);
int flag=min(resl,resr);
ans+=flag;
resl-=flag;
resr-=flag;
if(suml<resl||sumr<resr){puts("-1");return 0;}
ans+=resl+resr;
printf("%d",ans);
return 0;
}
rp++
[CSP-S模拟测试]:括号密码(贪心)的更多相关文章
- [CSP-S模拟测试]:Blue(贪心)
题目描述 $Blue$是个动物学家,不仅喜欢研究猫和老鼠,还喜欢研究青蛙.他最近开始研究青蛙过河的问题,可以简化成:数轴上$0$为岸边,$L$为河对岸.$(0,L)$中间存在$n$个石子.已知青蛙一跳 ...
- [CSP-S模拟测试]:爬(贪心)
题目传送门(内部题134) 输入格式 第一行两个数$N,L$. 接下来$N$行每行两个数$A_i,B_i$. 接下来$N$行每行一个整数$C_i$. 输出格式 一行一个整数表示答案,无解输出$-1$. ...
- [CSP-S模拟测试]:午餐(贪心+最短路)
题目传送门(内部题115) 输入格式 第一行两个正整数$n,m$. 接下来$m$行,每行$4$个正整数$u_j,v_j,L_j,R_j$. 接下来一行$n$个数,若第$i$个数为$1$,则$i$号同学 ...
- [CSP-S模拟测试]:格式化(贪心)
题目传送门(内部题105) 输入格式 每组数据第一行一个正整数$n$,表示硬盘块数,接下来$n$行,每行两个正整数,第一个正整数为硬盘格式化前的容量,第二个正整数为格式化之后的容量. 输出格式 对每组 ...
- [CSP-S模拟测试]:优化(贪心+DP)
题目描述 $visit\text{_}world$发现有下优化问题可以用很平凡的技巧解决,所以他给你分享了这样一道题:现在有长度为$N$的整数序列$\{ a_i\}$,你需要从中选出$K$个不想叫的连 ...
- [CSP-S模拟测试]:表达式密码(模拟)
题目传送门(内部题87) 输入格式 从文件$expression.in$中读入数据.输入一行,一个字符串$S$,表示原表达式,保证为合法表达式 输出格式 输出到文件$expression.out$中. ...
- [CSP-S模拟测试]:梦境(贪心+小根堆)
题目描述 智者奥尔曼曾说过:有缘的人即使相隔海角天涯,也会在梦境中相遇. $IcePrince\text{_}1968$和$IcePrincess\text{_}1968$便是如此.有一天$IcePr ...
- [CSP-S模拟测试]:d(贪心+树状数组)
题目传送门(内部题65) 输入格式 第一行,一个自然数$T$,代表数据组数.对于每组数据:第一行,一个正整数$n$,一个自然数$m$.接下来$n$行,每行两个正整数,$a_i,b_i$. 输出格式 对 ...
- [CSP-S模拟测试]:Tree(贪心)
题目描述 给定一颗$n$个点的树,树边带权,试求一个排列$P$,使下式的值最大 $$\sum \limits_{i=1}^{n-1}maxflow(P_i,P_{i+1})$$ 其中$maxflow( ...
随机推荐
- POJ2387 Til the Cows Come Home (最短路 dijkstra)
AC代码 POJ2387 Til the Cows Come Home Bessie is out in the field and wants to get back to the barn to ...
- Appium+Python之获取toast
思考:手机APP上的必填或错误文本提示一般1-2s就会消失,比较难定位,所以一般的固定元素定位方式是不可用的,那我们如何定位toast呢? 前提:1.Appium1.6.3以上(包括1.6.3) 2. ...
- python,pycharm环境安装
1.1 python3安装四部曲 第一步下载 地址 https://www.python.org/downloads/windows/ 第二步安装 1. 第三步 配置坏境变量 第四步 测试是否完成安装 ...
- 由对称性解2-SAT问题
由对称性解2-SAT问题 (by 伍昱,03年IOI国家集训队论文ppt) 2-SAT: 2-SAT就是2判定性问题,是一种特殊的逻辑判定问题. 2-SAT问题有何特殊性?该如何求解? 我们从一道例题 ...
- css 文本单行显示溢出时出现省略号 多行显示溢出时出现省略号 首行缩进
一.文本单行显示溢出时出现省略号 二.文本多行显示溢出时出现省略号(这种样式只能在webkit和移动端使用,包括小程序,不能设置固定高度) 三.首行缩进两字符 text-indent: 2em; 四. ...
- express-handlebars
https://www.npmjs.com/package/express-handlebars
- PHP WEB 引擎缓存加速优化
PHP 缓存加速器介绍 操作码缓存 请求一个 PHP 程序时,PHP 引擎会解析程序,并且将编译码作为特定操作码.这是要执行的代 码的一种二进制表示形式.随后,此操作码有 PHP 引擎执行并丢弃.操作 ...
- python算法(一)基本知识&冒泡排序&选择排序&插入排序
本节内容: 算法基本知识 冒泡排序 选择排序 插入排序 1. 算法基本知识 1.1 什么是算法? 算法(algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为 ...
- Django学习系列2:django环境中安装selenium并查看selenium版本号
在Django环境中安装selenium (django) root@ranxf-TEST:/studydisk/Python_web_TDD/superlists# conda install se ...
- 如何在通过脚手架create-react-app 创建的react项目中配置 less
首先感慨下 自己竟然有半年没登账户 ,干嘛去啦? 从刚接触vue 接手做两次版本之后 又让我这个小菜鸡 开始开发react项目,连react生命周期还没搞明白的时候 就开始进行第一版本的开发了,第一个 ...