【 Educational Codeforces Round 132 (Rated for Div. 2) A·B·C】

更好的阅读体验 \color{red}{更好的阅读体验} 更好的阅读体验



A. Three Doors


原题链接

Origional Link


思想

  • 从拿到钥匙的门开始,用其得到的钥匙遍历对应的门
  • 直到钥匙为 0 0 0,若共打开了 3 3 3道门,则为YES

代码

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

const int N = 10;

void solve(){
	
	int a[N];
	
	int n;
	
	cin >> n;
	
	int flag = 1;  //记录打开的门的数量
	
	for(int i = 1; i <= 3; i++) cin >> a[i];
	
	for(int i = n; a[i] != 0; i = a[i]) flag++; 
	
	if(flag == 3) cout << "YES" << "\n";
	else cout << "NO" << "\n";
	
}

int main(){
	
	int _;
	
	cin >> _;
	
	while(_--){
		solve();
	}
	
	return 0;
	
}

B. Also Try Minecraft


原题链接

Origional Link


思想

  • 利用前缀和与后缀和预处理区间的伤害值
  • 对于每个询问: l < r l<r l<r 为前缀, l > r l>r l>r 为后缀

注意:开long long!开long long!开long long


代码

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

#define int long long

const int N = 1e6 + 10;
 
int a[N];
 
int b[N],c[N];
 
void solve(){
	
	int n, m;
	
	cin >> n >> m;
	
	for(int i = 1 ; i <= n ; i++){
		
		cin >> a[i];
		
		if(a[i] < a[i-1]){
			b[i] = a[i-1] - a[i];  //处理前缀	
		}
		else if(a[i] > a[i-1]){
			c[i] = a[i] - a[i-1];   //处理后缀
		}
		
		b[i] += b[i-1];  //构造前缀和数组
		c[i] += c[i-1];  //构造后缀和数组
		
	}	
	
	while(m--){
		
		int l, r;
		
		cin >> l >> r;
		
		if(l < r){
			cout << b[r] - b[l] << "\n";
		}
		else cout << c[l] - c[r] << "\n";
		
	}
	
}
 
signed main(){
	
	solve();
	
	return 0;
	
}

C. Recover an RBS


原题链接

Origional Link


思想

  • 贪心
  • dep表示当前遍历到的还未配对的(的数量,vis表示当前遍历到的?的数量
  • 从左边向右遍历括号序列s
    • dep:若s[i] == '(',则dep++,若s[i] == ')',则dep--
    • vis:若s[i] == '?',则vis++
  • 在遍历过程中,dep的状态会影响序列的唯一性
    • dep < 0,则在之前遍历的序列中,必然存在至少一个?即(vis>0),使得括号序列合法,且?的状态将唯一确定,此时dep++,vis--
    • dep == 0 && vis == 1,则在之前遍历的序列中,?的状态也将唯一确定,此时dep++,vis--
  • 遍历结束后,由于遍历时depvis唯一确定的状态已经消去,故现在只剩下了还未确定唯一性状态的depvis
  • abs(dep) == vis,说明剩下的状态也将唯一确定并消去,该括号序列合法且唯一,反之则不符合。

代码

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

void solve(){
	
	string s;
	
	cin >> s;
	
	int dep = 0, vis = 0;
	
	for(int i = 0 ; i < s.size() ; i++){
		
		if(s[i] == '(') dep++;
		else if(s[i] == ')'){dep--;
			if(dep < 0){
				if(vis > 0)dep++, vis--;
				else{  //vis <= 0 说明无法匹配,序列非法
					dep = 1, vis = 0;
					break;
				}
			}
		}
		else vis++;
		
		if(dep == 0 && vis == 1) dep++, vis--; 
		
	}
	
	if(abs(dep) == vis) cout << "YES" << '\n';
	else cout << "NO" << '\n';
	
}

int main(){
	
	int _;
	
	cin >> _;
	
	while(_--){
		solve();
	}
	
	return 0;
	
}

后记

  • A A A题肥肠煎蛋,不过由于可选性的方法太多,一时间不知道选哪个最好,写的时候有点乱套
  • B B B题居然是以Terraira为背景的,本来还激动了一下,读懂题之后发现是前缀和,比较简单
    • 但是做的时候眼瞎,没看见 a i a_i ai的范围,不开long long吃了四发WA活该()

    • 在这里插入图片描述

    • 记得开long long!!!

    • 记得开long long!!!

    • 记得开long long!!!

  • C C C题遇到括号序列就不会,这次好好补补,贪心学不会的无力感QAQ
  • 最后发现 D D D过的居然比 C C C多?! D D D好像是st表的模板题,还没学,等我学完之后回来复仇
  • 读英文题一定要理解清楚,读假题太伤了。
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浪漫主义狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值