Codeforces Round 913 (Div. 3)

发布时间 2023-12-06 16:33:51作者: PHarr

A. Rook

#include <bits/stdc++.h>

using namespace std;


#define int long long
using pii = pair<int, int>;
using node = pii;
using i32 = int32_t;

void solve(){
    string s;
    cin >> s;
    for( char c = 'a' ; c <= 'h' ; c ++ ){
        if( c == s[0] ) continue;
        cout << c << s[1] << "\n";
    }
    for( char c = '1' ; c <= '8' ; c ++ ){
        if( c == s[1] ) continue;
        cout << s[0] << c << "\n";
    }
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for( cin >> TC ; TC ; TC -- )
        solve();
    return 0;
}

B. YetnotherrokenKeoard

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define mp make_pair

using vi = vector<int>;
using pii = pair<int, int>;

const int inf = 1e18;

void solve() {
    string s;
    cin >> s;
    vector<pair<int, char>> a, b;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] == 'b') {
            if (!a.empty()) a.pop_back();
        } else if (s[i] == 'B') {
            if (!b.empty()) b.pop_back();
        } else if ('a' <= s[i] and s[i] <= 'z')
            a.emplace_back(i, s[i]);
        else
            b.emplace_back(i, s[i]);
    }
    int i, j;
    for (i = 0, j = 0; i < a.size() and j < b.size();) {
        if( a[i].first < b[j].first ){
            cout << a[i].second;
            i ++;
        }else{
            cout << b[j].second;
            j ++;
        }
    }
    for( ; i < a.size() ; i ++ )
        cout << a[i].second;
    for( ; j < b.size() ; j ++ )
        cout << b[j].second;
    cout << '\n';
    return ;
}


int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    for (cin >> T; T; T--)
        solve();

    return 0;
}

C. Removal of Unattractive Pairs

想了想,实际上和摆放的位置是没有关系的,所以一定可以把所有的相邻且不同的消除掉。

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define mp make_pair

using vi = vector<int>;
using pii = pair<int, int>;

void solve() {
    int n;
    string s;
    cin >> n >> s;
    vi cnt(26);
    for (auto c: s) cnt[c - 'a']++;
    priority_queue<int> q;
    for (auto i: cnt) if (i > 0)q.push(i);
    for (int x, y; q.size() >= 2;) {
        x = q.top(), q.pop();
        y = q.top(), q.pop();
        x--, y--;
        if (x > 0) q.push(x);
        if (y > 0) q.push(y);
    }
    if (q.empty()) cout << "0\n";
    else cout << q.top() << "\n";

}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    for (cin >> T; T; T--)
        solve();

    return 0;
}

另一种考虑是思路是看出现次数最多是时候超过一半,如果没有超过就可以全部消掉。否则,最终剩下的就是出现最多的。

#include <bits/stdc++.h>

using namespace std;

#define int long long
using i32 = int32_t;
using vi = vector<int>;
const int inf = 1e18;

void solve() {
    int n;
    string s;
    cin >> n >> s;
    vi cnt(26);
    for (const auto &c: s) cnt[c - 'a']++;
    int m = *max_element(cnt.begin(), cnt.end());
    if (m * 2 <= n)
        cout << n % 2 << "\n";
    else
        cout << n - 2 * (n - m) << "\n";
    return;
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--) solve();
    return 0;
}

D. Jumping Through Segments

二分答案

check 就是维护每次可以达到区间并与目标区间求交集。如果为空集则移动范围小了。

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define mp make_pair

using vi = vector<int>;
using pii = pair<int, int>;

const int inf = 1e18;

void solve() {
    int n;
    cin >> n;
    vector<pii> a(n);
    for (auto &[l, r]: a) cin >> l >> r;
    int l = 0, r = 1e10, res = -1;
    auto check = [a](int k) {
        int l = 0, r = 0;
        for (const auto &[x, y]: a) {
            l -= k, r += k;
            l = max(  l , x ) , r = min( r , y );
            if( l > r ) return false;
        }
        return true;
    };
    for (int mid; l <= r;) {
        mid = (l + r) / 2;
        if (check(mid)) res = mid, r = mid - 1;
        else l = mid + 1;
    }
    cout << res << "\n";
}

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

E. Good Triples

可以注意到是,在进行加法的时候不能发生进位,所以直接统计每一位的拆分方式就好了。

#include <bits/stdc++.h>

using namespace std;

#define int long long
using vi = vector<int>;

const int inf = 1e18;
vi val( 10);

void solve() {
    int n;
    int res = 1;
    cin >> n;
    for( ; n ; n /= 10 )
        res *= val[n % 10];
    cout << res << "\n";
    return;

}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    for( int x = 0 ; x <= 9 ; x ++ ){
        for( int a = 0 ; a <= x ; a ++ )
            for( int b = 0 ; a + b <= x ; b ++ )
                val[x] ++;
    }

    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

F. Shift and Reverse

题目给的串实际上就是循环同构,所有循环起点就是一定水最小值,且起点的上一位一定是最大值,我们可以暴力的找到这个位置,然后判断序列是否非降序。如果是非降序的把起点移动过来就好了。移动起点的方式有两种,一种是向前移动,还有一种是翻转一次后向后移动,我们取两种移动步数少的即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long
using pii = pair<int, int>;
using node = pii;
using i32 = int32_t;
using vi = vector<int>;
const int inf = 1e18;

int minNotation(const vi s) {
    int n = s.size();
    int i = 0, j = 1;
    for (int k = 0; k < n and i < n and j < n;) {
        if (s[(i + k) % n] == s[(j + k) % n]) k++;
        else {
            if (s[(i + k) % n] > s[(j + k) % n]) i = i + k + 1;
            else j = j + k + 1;
            if (i == j) i++;
            k = 0;
        }
    }
    return min(i, j);
}

void solve() {
    int n, t, q;
    cin >> n;
    vi a(n), b(n);
    for (auto &i: a) cin >> i;
    t = *min_element(a.begin(), a.end());
    q = *max_element(a.begin(), a.end());
    int res = inf;
    for (int i = 0, f = 1; i < n; i++) {
        if (a[i] != t) continue;
        if (a[(i - 1 + n) % n] != q) continue;
        f = 1;
        for (int j = 1; j < n and f; j++) {
            if (a[(i + j) % n] >= a[(i + j - 1) % n]) continue;
            f = 0;
        }
        if (f) res = min(res, min((n - i) % n, i + 2));
        break;
    }
    reverse(a.begin(), a.end());
    for (int i = 0, f; i < n; i++) {
        if (a[i] != t) continue;
        if (a[(i - 1 + n) % n] != q) continue;
        f = 1;
        for (int j = 1; j < n and f; j++) {
            if (a[(i + j) % n] >= a[(i + j - 1) % n]) continue;
            f = 0;
        }
        if (f) res = min(res, min(i + 1, (n - i) % n + 1));
        break;
    }
    if (res == inf) cout << "-1\n";
    else cout << res << "\n";
    return;
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--)
        solve();
    return 0;
}