Educational Codeforces Round 163 (Rated for Div. 2)

在这里插入图片描述

Educational Codeforces Round 163 (Rated for Div. 2)

Educational Codeforces Round 163 (Rated for Div. 2)

A. Special Characters

题意:

给出特殊字符的定义,在一组字符串中当前字符的相邻字符有且仅有一个与自身相同的字符,找出具有n个特殊字符的字符串。

思路:

符合条件的字符串一定是成对出现的,所以奇数量特殊字符不可能,然后叠加出现一对特殊字符的情况即可。

AC code:

void solve() {
    cin >> n;
    if (n & 1) {
        cout << "NO" << endl;
        return;
    }
    cout << "YES" << endl;

    for (int i = 0; i < n / 2; i ++) {
        cout << "BBA";
    }
    cout << endl;
}

B. Array Fix

题意;

对于长度为n的序列a,可以对大于10的元素进行拆分,然后按原顺序插入序列中,是否可能通过这种操作使得序列非递减。

思路:

找到最靠后的一个不符合条件的元素,只有拆分操作有可能使得序列非递减,其之前的元素若大于10均需要拆分操作;

注意,若拆分前十进制整数ab中,a>b,则不可以进行拆分,否则拆分后插入原序列会导致序列无法达到非递减;

将操作后的序列进行二次判断,看是否是非递减。

AC code:

void solve() {
    cin >> n;
    vector<int> a(n);
    int f = 0;
    for (int i = 0; i < n; i ++) {
        cin >> a[i];
    }
    int pos = -1;
    for (int i = 0; i < n - 1; i ++) {
        if (a[i] > a[i + 1]) {
            pos = i;
        } 
    } 
    if (pos == -1) {
        cout << "YES" << endl;
        return;
    }
    vector<int> c;
    for (int i = 0; i <= pos; i ++) {
        int t = a[i];
        if (t < 10) c.pb(a[i]);
        else {
            int x = t / 10, y = t % 10;
            if (x <= y) c.pb(x), c.pb(y);
            else c.pb(t);
        }
    } 
    for (int i = pos + 1; i < n; i ++) c.pb(a[i]);
    for (int i = 1; i < c.size(); i ++) {
        //cout << c[i] << ' ';
        if (c[i] < c[i - 1]) {
            cout << "NO" << endl;
           return;
        }
    }
    cout << "YES" << endl;
}

C. Arrow Path

题意:

走迷宫,二进制字符串迷宫,每次有两次移动,第一次可以任意选择上下左右进行移动,第二次则根据第一次移动到的位置的字符判断是向左还是向右移动,第二次移动一定要有且与字符指向相同;

是否可以从(1, 1)走到(2, n)。

思路:

BFS直接按照题目要求走一遍,看是否能到达终点即可。

AC code:

void solve() {
    cin >> n;
    cin >> g[0] >> g[1];
    map<PII, int> st;
    
    queue<PII> q;
    q.push({0, 0});
    st[{0, 0}] = 1;
    int f[5] = {1, 0, -1, 0, 1};

    while (!q.empty()) {
        auto [i, j] = q.front();
        q.pop();
        for (int t = 0; t < 4; t ++) {
            int x = i + f[t], y = j + f[t + 1];
            if (x >= 0 && x < 2 && y >= 0 && y < n && !st[{x, y}]) {
                st[{x, y}] = 1;
                if (g[x][y] == '>' && !st[{x, y + 1}]) {
                    st[{x, y + 1}] = 1;
                    q.push({x, y + 1});
                } 
                if (g[x][y] == '<' && !st[{x, y - 1}]) {
                    st[{x, y - 1}] = 1;
                    q.push({x, y - 1});
                } 
            }
        }
    }
    if (st[{1, n - 1}]) cout << "YES" << endl;
    else cout << "NO" << endl;
}

D. Tandem Repeats?

题意:

给出由小写字母以及’?'组成的字符串,找出最长的串联字符子串(前半部分等于后半部分的字符串)。

思路:

首先是暴力枚举,找出所有可能长度的子串进行判断,O(n^3),会爆;

优化方案:

O(n^2)找出可能长度的子串,再单独判断该长度下符合条件的最长连续子串。

枚举的分别是可能串联子串折半的长度以及当前开始的位置,若对应位置子串相同或其一为’?'则当前字符符合串联条件。

AC code:

void solve() {
    cin >> s;
    n = s.size();
    int ans = 0;
    for (int i = 1; i <= n / 2; i ++) {
        vector<int> cnt;
        for (int j = 0; j < n; j ++) {
            if (i + j < n && (s[j] == s[j + i] || s[j] == '?' || s[j + i] == '?')) {
                cnt.pb(j);
            }
        }
        int t = 1;
        for (int x = 0; x < cnt.size(); x ++) {
            if (x == 0) t = 1;
            else if (cnt[x] == cnt[x - 1] + 1) t ++;
            else t = 1;
            //cout << t << " " << i << "++" << endl;
            if (t == i) {
                ans = max(ans, t * 2);
            }
        }
    }
    cout << ans << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值