Educational Codeforces Round 132 (Rated for Div. 2)

Educational Codeforces Round 132 (Rated for Div. 2)

A. Three Doors

简述

题意: 有三扇门(1~3), 其中两扇门后面有对应标号门的钥匙,现在手上有一把标号为n的钥匙,是否能打开所有的门?

判断现在有的钥匙 对应的门后 是否有钥匙即可,就是套娃 不是

Code
#define OK cout << (ok ? "YES" : "NO") << endl
void testcase() {
    int n, ok = 0;
    cin >> n;
    vector<int> a(4);
    for (int i = 1; i <= 3; ++i) cin >> a[i];
    if (a[n] and a[a[n]]) ok = 1;
    cout << (ok ? "YES" : "NO") << endl;
}

B. Also Try Minecraft

简述 题意: n个有高度的塔 ,向上飞不扣血,向下飞会扣血,每次询问判断从一个塔到另一个塔所扣的最少血

直接走过去肯定比来回走扣的血少,所以直接统计在询问的区间内会扣得血就行,前缀和预处理一下,由于可能从右向左走,要从前和从后做两遍前缀和

Code
int n, m;
cin >> n >> m;
vector<ll> a(n + 1), b(n + 1), c(n + 1);
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 2; i <= n; ++i) b[i] = b[i - 1] + max(0ll, a[i - 1] - a[i]);
for (int i = n - 1; i >= 1; --i) c[i] = c[i + 1] + max(0ll, a[i + 1] - a[i]);
while (m--) {
    int x, y;
    cin >> x >> y;
    if (x < y) cout << b[y] - b[x] << endl;
    else  cout << c[y] - c[x] << endl;
}

C. Recover an RBS

简述

题意: 一个括号序列,只含' ( ' , ' ) ' , ' ? ' 三种字符,可以将?替换为括号,是否只有唯一一种方案使得这个字符串的每个括号能匹配 也就是使它变为( ( ) )( ) 这种样子 题目保证最少有一种方案是它成为括号序列

要点1 : 题目保证的最少有一种方案 这意味着最后左括号右括号都等于字符串长度的一半

要点2 : 括号序列 意味着 对于字符串的每个位置之前的右括号个数一定小于等于左括号个数

先将 '?' 替换得到一组最简单的括号序列 尝试交换所能替换的最后一个 左括号 和其之后的右括号

看替换后的序列是否为括号序列,如果是括号序列说明方案数不唯一,输出NO

Code
void testcase() {
    string s; cin>>s;
    int cntl=0,cntr=0;
    vector<int>a;
    for(int i=0;i<s.length();++i){
        if( s[i] == '(' ) ++cntl;
        else if(s[i]==')') ++cntr;
        else a.emplace_back(i);
    }
    int mid=s.length()>>1;
    for(int i=0,en=(int)a.size();i<en;++i){
        if( i < mid-cntl ) s[a[i]] = '(';
        else s[a[i]] = ')' ;
    }
    bool ok=true;
    if(cntl<mid and cntr<mid){
        swap(s[a[mid-cntl-1]],s[a[mid-cntl]]);
        int cnt=0;
        for(int i=0;i<s.length();++i){
            if(s[i]=='(')++cnt;
            else --cnt;
            if(cnt<0) break;
        }
        if(cnt==0)ok=false;
    }
    cout << (ok ? "YES" : "NO") << endl;
}

D. Rorororobot

简述

机器人只能上下左右走固定的k步 每一列有从下往上的一定长度的障碍 不能走出界,是否可以从一个点到另一个点

先不看障碍判断是否可达 : 用%来判断 再看能不能找到一条路径走过去

判断是否能走过障碍:假如两个点之间有一堵高墙,每次只能跨k的距离 能不能走到最高的这堵墙与边界之间,如果可以走到就可达

Code
#define OK cout << (ok ? "YES" : "NO") << endl

template <typename T, class F = function<T(const T&, const T&)>>
class SparseTable {
public:
    int n;
    vector<vector<T>> mat;
    F func;

    SparseTable(const vector<T>& a, const F& f) : func(f) {
        n = static_cast<int>(a.size());
        debug(n);
        int max_log = 32 - __builtin_clz(n);
        mat.resize(max_log);
        mat[0] = a;
        for (int j = 1; j < max_log; j++) {
            mat[j].resize(n - (1 << j) + 1);
            for (int i = 0; i <= n - (1 << j); i++) {
                mat[j][i] = func(mat[j - 1][i], mat[j - 1][i + (1 << (j - 1))]);
            }
        }
    }
    T get(int from, int to) const {
        assert(0 <= from && from <= to && to <= n - 1);
        int lg = 32 - __builtin_clz(to - from + 1) - 1;
        return func(mat[lg][from], mat[lg][to - (1 << lg) + 1]);
    }
};
void testcase() {
    int n, m;
    cin >> n >> m;
    vector<int> a(m);
    for (int& i : a) cin >> i;
    SparseTable<int> st(a, [&](int i, int j) { return max(i, j); });
    int q;
    cin >> q;
    while (q--) {
        int sx, sy, tx, ty, k;
        cin >> sx >> sy >> tx >> ty >> k;
        int x = abs(sx - tx), y = abs(sy - ty);
        bool ok = false;
        if (x % k and y % k) {
            OK;
            continue;
        }
        int now = tx + (n - tx - (n - tx) % k);
        if (sy > ty) swap(sy, ty);
        int mx = st.get(sy - 1, ty - 1);
        if (now > mx) ok = true;
        OK;
    }
}

EF 待补

posted @ 2022-07-23 23:06  Cattle_Horse  阅读(36)  评论(0编辑  收藏  举报