Educational Codeforces Round 132 A-C, D待补

目录

题目

A. Three Doors

题意:

思路:

code:

B. Also Try Minecraft

题意:

思路:

code:

C. Recover an RBS

题意:

思路:

code:

D. Rorororobot

总结


题目

A. Three Doors

题意:

一共三扇门, 其中两个后面有一把钥匙,钥匙能开对应的门, 开始的时候给你一把钥匙, 问你能不能通过这把钥匙开所有的门.

思路:

题意描述的不太开, 总之就是个简单的模拟操作. map记录下每个门后面对应的钥匙, 再检查是否能通过给你的钥匙开所有的门即可.

code:

/**
 *    author:  CurleyD
 *    created: 07.22.2022 10:26:48
**/
#include <bits/stdc++.h>
using namespace std;
#define fastIO ios::sync_with_stdio(false); cin.tie(nullptr);
#define debug cout<<"\nStop Here\n"; return;
#define per(i,a,n) for(int i=n;i>=a;i--)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define eb emplace_back
#define pb push_back
#define se second
#define fi first
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const ll MOD = 1000000007;
const db eps = 1e-6;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
//#define int long long
//head

int T = 1, n, m;

void solve() {
    cin >> n;
    map<int,int> mp;
    for (int i = 1; i <= 3; i++) {
        int x;
        cin >> x;
        mp[i] = x;
    }
    int t = mp[n];
    int cnt = 1;
    while (cnt < 3 && t != 0) {
        cnt ++;
        t = mp[t];
    }
    if (cnt == 3) 
        cout << "YES\n";
    else 
        cout << "NO\n";
}

signed main() {
    fastIO
    cin >> T;
    while(T--) {solve();}
    return 0;
}

B. Also Try Minecraft

题意:

从1~n按编号给你n个高度a_1...1_n, 从高度低的到高度高的需要花费a_{high}-a_{low}.现在给你m个查询, 问你每次从lr的需要花费多少.

思路:

会爆int, 注意开long long (我#define int long long 了)

开始想着直接一个前缀和就可以解决, 但看到样例有从右向左走的, 联想到逆序的时候又需要一个新的前缀和, 因此两个前缀和扫一遍, 查询的时候分成 1)l < r 2)l > r 来算即可.

code:

/**
 *    author:  CurleyD
 *    created: 07.22.2022 10:26:48
**/
#include <bits/stdc++.h>
using namespace std;
#define fastIO ios::sync_with_stdio(false); cin.tie(nullptr);
#define debug cout<<"\nStop Here\n"; return;
#define per(i,a,n) for(int i=n;i>=a;i--)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define eb emplace_back
#define pb push_back
#define se second
#define fi first
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const ll MOD = 1000000007;
const db eps = 1e-6;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
#define int long long
//head

int T = 1, n, m;

void solve() {
    cin >> n >> m;
    vector<int> a(n + 1);
    vector<int> sum1(n + 1);
    vector<int> sum2(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 2; i <= n; i++) {
        if (a[i] > a[i-1])
            sum1[i] = a[i] - a[i-1];
        sum1[i] += sum1[i-1];
    }
    for (int i = n - 1; i >= 1; i--) {
        if (a[i] > a[i+1])
            sum2[i] = a[i] - a[i+1];
        sum2[i] += sum2[i+1];
    }
    while (m--) {
        int l, r;
        cin >> l >> r;
        if (l > r) {
            cout << sum1[l] - sum1[r] << endl;
        }
        else {
            cout<<sum2[l] - sum2[r]<<endl;
        }
    }
}

signed main() {
    fastIO
    // cin >> T;
    while(T--) {solve();}
    return 0;
}

C. Recover an RBS

题意:

对于给出的由"?", "(", ")"构成的字符串, 问你是否存在唯一的正则括号序列? (关于正则括号序列regular bracket sequence详细的请自行题干)

思路:

贪心

做的时候没什么想法, 后来看了群里大佬的题解, 理解了七七八八. 唯一性证明不太理解

我所想到的对保证唯一性的方法就是:对于每个问号都变成左括号去和未匹配的右括号配对, 进而保证一定是最优的从而不满足这个条件的就不算是YES, 进而推出唯一性?

cnt记录问号数量, dep记录当前有的未匹配的左/右括号数量, 大于0表是当前有未匹配的左括号, 小于0表示当前有未匹配的右括号. 我们for遍历一下串s, 会有以下情况

1)遇到左括号那么dep ++.

2)遇到右括号dep -- 在这个条件中可能遇到dep < 0即却左括号, 那么我们把问号转化成左括号cnt --, 进而让dep ++, 消除了未配对的右括号(似乎这里保证了最优/唯一性)

3)问号 cnt ++

4)dep = 0 && cnt = 1, 已经有的左右括号全部匹配, 但其中有这问号. 那么这个问号一定不能是右括号! 只能是左括号, 因此我们可以直接将其转化成左括号! cnt -- dep ++

code:

/**
 *    author:  CurleyD
 *    created: 07.22.2022 12:20:38
**/
#include <bits/stdc++.h>
using namespace std;
#define fastIO ios::sync_with_stdio(false); cin.tie(nullptr);
#define debug cout<<"\nStop Here\n"; return;
#define per(i,a,n) for(int i=n;i>=a;i--)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define eb emplace_back
#define pb push_back
#define se second
#define fi first
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const ll MOD = 1000000007;
const db eps = 1e-6;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
//#define int long long
//head

int T = 1, n, m;

void solve() {
    int dep = 0;
    string s;
    cin >> s;
    int cnt = 0;
    for (auto c : s) {
        if (c == '(')
            dep ++;
        else if (c == ')'){
            dep --;
            if (dep < 0) {
                dep ++;
                cnt --;
            }
        }
        else
            cnt ++;
        if (dep == 0 && cnt == 1)
            dep ++, cnt = 0;
    }
    if (abs(dep) == cnt)
        cout << "YES\n";
    else
        cout << "NO\n";
}

signed main() {
    fastIO
    cin >> T;
    while(T--) {solve();}
    return 0;
}

D. Rorororobot

待补. 区间查询最值, 需要用到ST表/线段树. 等到补了这个知识点回来搞D.

总结

昨天睡着了, 没在赛时打, 早上起来补掉了但打了估计也是2题orz, A,B很签就是实现的慢了点, 半小时才出这俩, 后来C实在没思路去吃饭了... 感觉问题在于, 有了想法, 不能在最快的时间用最短的/最精确的代码实现. 有的时候还会明知道自己想的不对, 但一路走到黑... 思维需要更跳脱一些, 像多校那几个签到不要明明有能力写出, 但卡在一些不该卡的方面上. 下场CF争取按时打. (不过这两天恢复了正常作息早7晚10, 好耶LoL) 希望下场多校都1A签到, 自己能多签几个...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值