A - Three Doors
题意
有三扇门,每扇门有一把匹配的钥匙。初始会给一扇门的钥匙,并在其中两扇门后面分别放下另外两把钥匙,求能否将三扇门全部开启
题解
每次按照当前可以打开的门进行跳转,当遇到 0 0 0 的时候退出,判断当前是否已经打开了三扇门。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll _;
/*-------------------------------------------------*/
/*-------------------------------------------------*/
ll n,m;
void solve(){
cin>>n;
int a[5],cnt=1;
for(int i=1;i<=3;i++){
cin>>a[i];
}
while(a[n]){
n=a[n];
cnt++;
}
if(cnt==3)puts("YES");
else puts("NO");
}
int main(){
cin>>_;while(_--)
solve();
return 0;
}
B - Also Try Minecraft
题意
给一个长度为 n n n 的数组, a i a_i ai 表示 i i i 位置的楼层高度。每次可以向左或向右移动一个单位,从高处移动到低处会获得值为高度差的摔落伤害,求从 s s s 移动到 t t t 获得的摔落伤害。
题解
因为起点可以比终点大,也可以比终点小,所以求出两个前缀和,一个是从从左到右的 a [ i ] − a [ i − 1 ] a[i]-a[i-1] a[i]−a[i−1] 的前缀和另一个是从做左到右 a [ i − 1 ] − a [ i ] a[i-1]-a[i] a[i−1]−a[i] 的前缀和,因为这样是起点大于终点就进行交换,这样就可以按照同样的逻辑求两种情况了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll _;
/*-------------------------------------------------*/
/*-------------------------------------------------*/
ll n,m;
ll a[N];
ll s1[N];//l->r
ll s2[N];//r->l
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<n;i++){
ll t1=max(0ll,a[i]-a[i+1]);
ll t2=max(0ll,a[i+1]-a[i]);
s1[i]=s1[i-1]+t1;
s2[i]=s2[i-1]+t2;
}
while(m--){
int s,t;
cin>>s>>t;
if(s<=t){
cout<<s1[t-1]-s1[s-1]<<endl;
}else{
swap(s,t);
cout<<s2[t-1]-s2[s-1]<<endl;
}
}
}
int main(){
//cin>>_;while(_--)
solve();
return 0;
}
C - Recover an RBS
题意
给定一个由 " ? ? ? “,” ( ( ( “,” ) ) ) " 组成的字符串。其中 ? ? ? 可以转换为左括号或右括号,判定当前字符串是否是唯一匹配的。
- 唯一匹配:要是出现 ? ? ? 既可以是左括号也可以是右括号,这样就不是唯一匹配。
题解
本题主要是判定怎样才是唯一的。这里我给出三个样例:
- ( ? ? ) (??) (??)
- ( ? ? ( ) ) ? ) (??())?) (??())?)
- ( ) ? ? ()?? ()??
在匹配的时候有几个规则:
(1) ) ) ) 优先匹配 ( ( ( 要是不存在 ( ( ( 就匹配 ? ? ?。
(2) ( ( ( 全部匹配完全且仅剩一个 ? ? ? 就将这个 ? ? ? 转换为 ( ( (。
(3)可以发现,要是左右两边在匹配的情况下还有
?
?
? 的剩余,这样就是不唯一的。
【刚又去看了一下,发现题目中有说一定存在至少一个匹配的情况所以是不会有 “((???((”这样的数据(还以为要被hack了)】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll _;
/*-------------------------------------------------*/
/*-------------------------------------------------*/
ll n,m;
void solve(){
string str;
cin>>str;
int cntl=0,cnt=0;
for(int i=0;i<str.size();i++){
if(str[i]=='('){
cntl++;
}else if(str[i]==')'){
if(!cntl){
cnt--;
}else{
cntl--;
}
}else{
cnt++;
}
if(cnt==1&&!cntl){
cnt--;
cntl++;
}
}
cnt-=cntl;
if(!cnt)puts("YES");
else puts("NO");
}
int main(){
cin>>_;while(_--)
solve();
return 0;
}