Educational Codeforces Round 132 (Rated for Div. 2)(补题C、D)

Educational Codeforces Round 132 (Rated for Div. 2)

C. Recover an RBS

题意

给你一串字符串,只含’'(',')','?',其中’?'可以是左括号也可以是右括号

问你是否只有一种括号匹配(保证至少有一种)

数据范围:2e5

tags:思维

思路

先把可以确定的?确定好

len为未匹配的括号数(若大于0则是有多的’‘(’‘,若小于0则是有多的’‘)’‘),q为已有的’?'的数

从头开始遍历

  1. 若遇到’('则len++
  2. 若遇到’)'则len–
    1. 此时可能会出现 l e n = = − 1 len==-1 len==1的情况,这种情况后面的括号无法去匹配该括号,于是只能把前面的一个’?‘变成’('。于是有len++;q--;
  3. 若遇到’?',则q++
  4. 最后需要在此判断,若len==0&&q==1,那么前面那唯一一个’?‘一定为’(‘,若为’)'则无法匹配。于是有len++;q--。因为前面三种情况都可能导致这种情况发生,所有此特判最后进行

遍历完之和,在根据为匹配的括号数len于剩余的问号数q进行判断

  1. abs(len)==q,说明q个问号已经被唯一确定去匹配多余的括号
  2. abs(len)!=q,说明有多的问号未确定,那么这些问号可以有多种组合,只要保证最后的len=0就行

代码

#include<iostream>
#include<bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t;
    for(cin>>t;t;t--){
        string s;
        cin>>s;
        int len=0,q=0;
        for(int i=0;i<s.length();i++){
            if(s[i]=='('){
                len++;
            }
            else if(s[i]==')'){
                len--;
                if(len==-1){
                    q--;
                    len++;
                }
            }
            else {
                q++;
            }
            if(len==0&&q==1){
                q--;
                len++;
            }
            // cout<<len<<' '<<q<<endl;
        }
        if(abs(len)==q)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}

D. Rorororobot

题意

n ∗ m n*m nm表格,其中第i列中从底到高有ai个格子不能走,剩余的n-ai的格子可以走。一个机器人每次可以向上下左右走k步,有q次询问,问是否可以从起点走到终点

数据范围: 1 ≤ n ≤ 1 0 9 , 1 ≤ m ≤ 2 ∗ 1 0 5 , 1 ≤ q ≤ 2 ∗ 1 0 5 1 \leq n \leq 10^9,1 \leq m \leq 2*10^5,1 \leq q \leq 2*10^5 1n109,1m2105,1q2105

tags:线段树(区间查询),思维

思路

由于不能走的地方都在最小下面,为了方便判断让起点和终点一起上移到最高点处sx+=(n-sx)/k*k;ex+=(n-ex)/k*k;

  1. 若最高点处不一样,则NO
  2. 判断能否以k为跨度横向走到终点去(abs(sx-ex)%k==0),若不能则NO
  3. 判断区间sy到ey的障碍物最高是否大于自身最高点,此处需要用线段树维护区间最大值,若高于则NO,否则YES

细节:注意sy可能大于ey,这时区间查询的时候就要交换一下

代码

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e9,maxm=2e5;
int n,m,q;
int h[maxm];
struct Node{
    int l,r,mx;
}tree[4*maxm];

void build(int k,int l,int r){
    tree[k].l=l,tree[k].r=r;
    if(r==l){
        tree[k].mx=h[l];
        return;
    }
    int mid=(l+r)>>1;
    build(2*k,l,mid);
    build(2*k+1,mid+1,r);
    tree[k].mx=max(tree[2*k].mx,tree[2*k+1].mx);
}

int query(int k,int l,int r){
    if(tree[k].l==l&&tree[k].r==r)return tree[k].mx;
    int mid=(tree[k].l+tree[k].r)>>1;
    if(r<=mid)return query(2*k,l,r);
    else if(l>mid)return query(2*k+1,l,r);
    else return max(query(2*k,l,mid),query(2*k+1,mid+1,r));
}


int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=m;i++)cin>>h[i];
    build(1,1,m);
    cin>>q;
    while(q--){
        int sx,sy,ex,ey,k;
        cin>>sx>>sy>>ex>>ey>>k;
        sx+=(n-sx)/k*k;
        ex+=(n-ex)/k*k;
        if(sx!=ex||!(abs(sy-ey)%k==0)){
            cout<<"NO"<<endl;
            continue;
        }
        if(sy>ey)swap(sy,ey);
        int mx=query(1,sy,ey);
        if(sx>mx)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}
  • 记得学一学区间查询最值的ST表💬
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值