Educational Codeforces Round 123

A. Doors and Keys

#include <bits/stdc++.h>

using namespace std;

#define int long long

void solve() {
    string s;
    cin >> s;
    map<char,int> pos;
    for( int i = 0 ; i < 6 ; i ++ )
        pos[s[i]] = i;
    if( pos['r'] < pos['R'] and pos['g'] < pos['G'] and pos['b'] < pos['B'] )
        cout << "YES\n";
    else
        cout << "NO\n";

}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

B. Anti-Fibonacci Permutation

暴力枚举前两位,暴搜后面的。

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 55;
array<int, N> a, vis;
int n , cnt;

void dfs( int i ){
    if( cnt == n ) return;
    if( i == n+1 ){
        for( int i = 1 ; i <= n ; i++ )
            cout << a[i] << " ";
        cout << "\n";
        cnt ++;
        return ;
    }
    for( int j = 1 ; j <= n ; j ++ ){
        if( vis[j] or j == a[i-1] + a[i-2] ) continue;
        a[i] = j , vis[j] = 1;
        dfs( i + 1 );
        vis[j] = 0;
    }
    return ;
}

void solve() {
    cin >> n , cnt = 0;
    fill(vis.begin(), vis.end(), 0);
    for (a[1] = 1; a[1] <= n and cnt != n ; a[1]++)
        for (a[2] = 1; a[2] <= n and cnt != n ; a[2]++)
            if (a[1] != a[2])
                vis[a[1]] = vis[a[2]] = 1, dfs(3), vis[a[1]] = vis[a[2]] = 0;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

C. Increase Subarray Sums

\(f[i][j]\)表示前\(i\)位加了\(j\)\(x\)的最大值。

因为题目要求了连续子区间,所以转移只有两类,一类是自己做起点,另一类是从前一个转移过来。

#include <bits/stdc++.h>

using namespace std;

#define int long long

void solve() {
    int n , x;
    cin >> n >> x;
    vector<int> a(n+1) , res(n+1);
    for( int i = 1 ; i <= n ; i ++ ) cin >> a[i];
    vector<vector<int>> f( n+1 , vector<int>(n+1 , INT_MIN));
    for( int i = 1 ; i <= n ; i ++ ){
        for( int j = 0 ; j <= n ; j ++ ){
            f[i][j] = max( a[i] , f[i-1][j] + a[i] );
            if( j > 0 ) f[i][j] = max( { f[i][j] , a[i] + x , f[i-1][j-1] + a[i] + x } );
            f[i][j] = max( f[i][j] , 0ll );
            res[j] = max( res[j] , f[i][j] );
        }
    }
    for( auto i : res )
        cout << i << " ";
    cout << "\n";
    return ;
}


int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

D. Cross Coloring

每一行,每一列只有最后一次染色有效,所以我们倒序来做。

维护每一行每一列是否被染色。并且如果所有的行或列都被染色了,就不能继续染了。

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int mod = 998244353;

const int N = 2e5 + 5;
array<int, N> x, y, r, c;

void solve() {
    int n, m, k, q;
    cin >> n >> m >> k >> q;
    fill(x.begin(), x.end(), 0);
    fill(y.begin(), y.end(), 0);
    for (int i = 1; i <= q; i++) cin >> r[i] >> c[i];
    int res = 1;
    for (int i = q, cntX = 0, cntY = 0; i >= 1; i--) {
        if (cntX == n or cntY == m or (x[r[i]] + y[c[i]] == 2))
            continue;
        if (x[r[i]] == 0)
            x[r[i]] = 1, cntX++;
        if (y[c[i]] == 0)
            y[c[i]] = 1, cntY++;
        res = res * k % mod;
    }
    cout << res << "\n";
    return;
}


int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) solve();
    return 0;
}

E. Expand the Path

这道题我认为写的最好的就是官解。

能够被访问的单元格一在下两条路径所形成的空间内:

  • 第一个R重复次数最多,然后最后一个D重复次数最多;
  • 第一个D重复次数最多,然后最后一个R重复次数最多。

这点其实还是比较好想的,官解大部分篇幅就是在证明这一点,我们直接跳过就好了。

求解中间部分的面积是本题的难点。实际上我们可以知道的是空的部分一定是左上角和右下角。我们考虑求出这两部分的面积即可。

对于左上角,我们从下往上一行一行的看,当前行空了\(y\)列。我们倒序看操作数组,如果s[i]=R,则y++,否则会向上移动一行,此时我们要把y累加到答案中去。只要模拟这个过程就可以算出左上角的面积。

对于右下角,我们翻转原序列统计过程就和上一步完全相同。

官解最妙其实是写法,不需要真的去扩展数组,

这里看到了,其实第一个\(R\)的目的是为了把其他的操作推到最后后面,所以第一个\(R\)之前对应的\(D\)累加的都是\(n-1\),这也是为什么要倒序处理操作序列。

#include <bits/stdc++.h>

using namespace std;

#define int long long

int calc(string s, int n) {
    int l = s.find('R'), ans = l * (n - 1);
    for (int i = s.size() - 1, y = 0; i > l; i--) {
        if (s[i] == 'D') ans += y;
        else y++;
    }
    return ans;
}

void solve() {
    int n;
    string s;
    cin >> n >> s;
    if (s == string(s.size(), s[0])) {
        cout << n << "\n";
        return;
    }
    int res = n * n;
    res -= calc(s, n);
    for (auto &i: s)
        i = (i == 'R' ? 'D' : 'R');
    res -= calc(s, n);
    cout << res << "\n";
    return;
}

int32_t main() {
    ios::sync_with_stdio(0), cin.tie(0);
    int t;
    for (cin >> t; t; t--)
        solve();
    return 0;
}
posted @ 2023-09-01 22:22  PHarr  阅读(7)  评论(0编辑  收藏  举报