2021蓝桥杯B组C++真题题解(三)

简介: 2021蓝桥杯B组C++真题题解

I:双向排序


题目描述

给定序列 (a1,a2,⋅⋅⋅,an)=(1,2,⋅⋅⋅,n),即ai=i。


小蓝将对这个序列进行 mm 次操作,每次可能是将 a1,a2,⋯,aqi 降序排列,或者将 aqi,aqi+1,⋯,an 升序排列。


请求出操作完成后的序列。


输入描述

输入的第一行包含两个整数 n,m,分别表示序列的长度和操作次数。


接下来 mm 行描述对序列的操作,其中第 i 行包含两个整数 pi,qi 表示操作类型和参数。当 pi=0 时,表示将 a1,a2,⋅⋅⋅,aqi 降序排列;当 pi=1 时,表示将 a_{q_i} , a_{q_{i+1}}, \cdots, a_naqi,aqi+1,⋯,an 升序排列。


输出描述

输出一行,包含 nn 个整数,相邻的整数之间使用一个空格分隔,表示操作完成后的序列。


输入输出样例

示例


输入

3 3
0 3
1 2
0 2

输出

3 1 2

样例说明

原数列为 ((1,2,3)。


第 11 步后为 (3,2,1)。


第 22 步后为(3,1,2)。


第 33 步后为 (3,1,2)。与第 22 步操作后相同,因为前两个数已经是降序了。


评测用例规模与约定

对于 30% 的评测用例,1n,m≤1000;


对于 60\%60% 的评测用例, 1<n,m≤5000;


对于所有评测用例,1≤n,m≤100000,0≤pi≤1,1≤qi≤n。


运行限制

语言 最大运行时间 最大运行内存
C++ 1s 256M
C 1s 256M
Java 1s 256M
Python3 1s 256M

用sort只能通过60,

#include <iostream>
#include <algorithm>
using namespace std;
int n,m;
int a[100005];
bool pai(int x,int y){
  return x>y;
}
int main(){
  cin>>n>>m;
  for(int i=0;i<n;i++){
    a[i]=i+1;
  }
  for(int i=0;i<m;i++){
    int x,y;
    cin>>x>>y;
    if(x==0){
      sort(a,a+y,pai);
    }
    else{
      sort(a+y-1,a+n);   //注意是n
    }
  }
  for(int i=0;i<n;i++){
    if(i!=n-1){
      cout<<a[i]<<' ';
    }
    else{
      cout<<a[i];
    }
  }
  return 0;
}



AC代码

#include <iostream>
using namespace std;
const int N = 100010;
pair<int, int> stk[N];
int ans[N];
int main() {
  int n, m, top = 0;
  cin >> n >> m;
  while (m--) {
    int p, q;
    cin >> p >> q;
    if (p == 0) {
      while (top && stk[top].first == 0) {
        q = max(q, stk[top--].second);
      }
      while (top >= 2 && stk[top - 1].second <= q) {
        // 如果当前操作比上一次相同操作的范围要大,那此次操作的前两次操作都将被无效化 
        top -= 2;
      }
      stk[++top] = {0, q};
    } else if (top) {
      while (top && stk[top].first == 1) {
        q = min(q, stk[top--].second);
      }
      while (top >= 2 && stk[top - 1].second >= q) {
        // 如果当前操作比上一次相同操作的范围要大,那此次操作的前两次操作都将被无效化 
        top -= 2;
      }
      stk[++top] = {1, q};
    }
  }
  int left = 1, right = n, k = n;
  for (int i = 1; i < top + 1; i++) {
    if (stk[i].first == 0) {
      while (right > stk[i].second && left < right + 1) {
        ans[right--] = k--;
      }
    } else {
      while (left < stk[i].second && left < right + 1) {
        ans[left++] = k--;
      }
    }
    if (left > right) {
      break;
    }
  }
  if (top % 2) {
    while (left < right + 1) {
      ans[left++] = k--;
    }
  } else {
    while (left < right + 1) {
      ans[right--] = k--;
    }
  }
  for (int i = 1; i < n + 1; i++) {
    cout << ans[i] << " ";
  }
  return 0;
}

J:括号队列


题目描述

给定一个括号序列,要求尽可能少地添加若干括号使得括号序列变得合法,当添加完成后,会产生不同的添加结果,请问有多少种本质不同的添加结果。


两个结果是本质不同的是指存在某个位置一个结果是左括号,而另一个是右括号。


例如,对于括号序列 (((),只需要添加两个括号就能让其合法,有以下几种不同的添加结果:()()()、()(())、(())()、(()()) 和((()))。


输入描述

输入一行包含一个字符串 s,表示给定的括号序列,序列中只有左括号和右括号。


输出描述

输出一个整数表示答案,答案可能很大,请输出答案除以 1000000007 (即 10^9 + 7)109+7) 的余数。


输入输出样例

示例 1


输入

((()

输出

5

评测用例规模与约定

对于 40%的评测用例,∣s∣≤200。


对于所有评测用例,1≤∣s∣≤5000。


运行限制

最大运行时间:5s

最大运行内存: 512M

 与其说一个规则,不如说是一个判断是否添加括号方法,在正常遍历字符串的时候,如果在当前遍历的位置的条件下,左括号数量大于右括号的数量,那么还不添括号,因为再往后遍历字符串的过程中还可能遇见右括号。如果在当前遍历的位置的条件下,左括号数量小于右括号的数量,那么需要添括号,因为再往后遍历字符串的过程中即使可能遇见左括号,也无法匹配之前的右括号    例如:)(  这样是不匹配的。


大佬的代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
using LL=long long;
const int N = 5005;
int f[N][N];
int mod=1e9+7;
string s;
int n;
LL get(){
    memset(f,0,sizeof f);
    f[0][0]=1;
    for(int i=1;i<=n;i++){
        if(s[i-1]=='('){
            for(int j=1;j<=n;j++)
                f[i][j]=f[i-1][j-1];
        }
        else{
            f[i][0]=(f[i-1][1]+f[i-1][0])%mod;
            for(int j=1;j<=n;j++)
                f[i][j]=(f[i-1][j+1]+f[i][j-1])%mod;
        }
    }
    for(int i=0;i<=n;i++)
        if(f[n][i])
            return f[n][i];
    return -1;
}
int main(){
    cin>>s;
    n=s.size();
    LL x=get();
    reverse(s.begin(),s.end());
    for(int i=0;i<n;i++){
        if(s[i]==')')
            s[i]='(';
        else
            s[i]=')';
    }
    LL y=get();
    cout<<(x*y)%mod;
}

相关文章
|
4月前
|
算法 测试技术 C++
小唐开始刷蓝桥(八)2013年第四届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(八)2013年第四届C/C++ B组蓝桥杯省赛真题
|
4月前
|
算法 C++ 数据格式
小唐开始刷蓝桥(七)2014年第五届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(七)2014年第五届C/C++ B组蓝桥杯省赛真题
|
4月前
|
算法 C++
小唐开始刷蓝桥(五)2016年第七届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(五)2016年第七届C/C++ B组蓝桥杯省赛真题
|
4月前
|
算法 C++
小唐开始刷蓝桥(六)2015年第六届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(六)2015年第六届C/C++ B组蓝桥杯省赛真题
|
4月前
|
人工智能 搜索推荐 C++
小唐开始刷蓝桥(一)2020年第十一届C/C++ B组第二场蓝桥杯省赛真题
小唐开始刷蓝桥(一)2020年第十一届C/C++ B组第二场蓝桥杯省赛真题
|
4月前
|
机器学习/深度学习 存储 人工智能
小唐开始刷蓝桥(三)2018年第九届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(三)2018年第九届C/C++ B组蓝桥杯省赛真题
|
4月前
|
存储 人工智能 算法
小唐开始刷蓝桥(四)2017年第八届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(四)2017年第八届C/C++ B组蓝桥杯省赛真题
|
4月前
|
存储 人工智能 Java
小唐开始刷蓝桥(二)2019年第十届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(二)2019年第十届C/C++ B组蓝桥杯省赛真题
|
4月前
|
数据安全/隐私保护 C++
小唐开始刷蓝桥(九)2012年第三届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(九)2012年第三届C/C++ B组蓝桥杯省赛真题
|
4月前
|
存储 人工智能 算法
第十四届蓝桥杯C++B组编程题题目以及题解
第十四届蓝桥杯C++B组编程题题目以及题解