Educational Codeforces Round 132 (Rated for Div. 2)
C. Recover an RBS
题意
给你一串字符串,只含’
'(',')','?'
,其中’?'可以是左括号也可以是右括号问你是否只有一种括号匹配(保证至少有一种)
数据范围:2e5
tags:思维
思路
先把可以确定的?确定好
len为未匹配的括号数(若大于0则是有多的’‘(’‘,若小于0则是有多的’‘)’‘),q为已有的’?'的数
从头开始遍历
- 若遇到’('则len++
- 若遇到’)'则len–
- 此时可能会出现 l e n = = − 1 len==-1 len==−1的情况,这种情况后面的括号无法去匹配该括号,于是只能把前面的一个’?‘变成’('。于是有
len++;q--;
- 若遇到’?',则q++
- 最后需要在此判断,若
len==0&&q==1
,那么前面那唯一一个’?‘一定为’(‘,若为’)'则无法匹配。于是有len++;q--
。因为前面三种情况都可能导致这种情况发生,所有此特判最后进行
遍历完之和,在根据为匹配的括号数len于剩余的问号数q进行判断
- 若
abs(len)==q
,说明q个问号已经被唯一确定去匹配多余的括号- 若
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 n∗m表格,其中第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 1≤n≤109,1≤m≤2∗105,1≤q≤2∗105
tags:线段树(区间查询),思维
思路
由于不能走的地方都在最小下面,为了方便判断让起点和终点一起上移到最高点处:sx+=(n-sx)/k*k;ex+=(n-ex)/k*k;
- 若最高点处不一样,则NO
- 判断能否以k为跨度横向走到终点去
(abs(sx-ex)%k==0)
,若不能则NO - 判断区间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表💬