Educational Codeforces Round 76

A. Two Rival Students

让两个人向两侧走就好了。

#include <bits/stdc++.h>

using namespace std;

void solve(){
    int n , x , a , b;
    cin >> n >> x >> a >> b;
    if( a > b ) swap( a , b );
    while( x > 0 && a > 1 ) x -- , a --;
    while( x > 0 && b < n ) x -- , b ++;
    cout << b-a<<"\n";
}

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

B. Magic Stick

只要能让\(a\)变的比\(b\)大就一定有解。

\(a\)不能无限变大的情况只有\(1,2,3\)特判即可

#include <bits/stdc++.h>

using namespace std;

void solve(){
    int x , y;
    cin >> x >> y;
    if( x == 1 && y != 1 ) cout << "NO\n";
    else if( x == 3 && y > 3 ) cout << "NO\n";
    else if( x == 2 && y > 3 ) cout << "NO\n";
    else cout << "YES\n";
    return ;
}

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

C. Dominated Subarray

可以知道的是,所谓的众数只要保证子区间有两个相同的数,其他数只有一个即可,并且其他情况一定可以通过拆分区间变成这种最简的情况。

这种情况下用一个双指针就可以\(O(n)\)枚举区间求解。

#include <bits/stdc++.h>

using namespace std;

void solve(){
    int n;
    cin >> n;
    vector<int> vis(n+1) , a(n+1);
    for( int i = 1 ; i <= n ; i ++ )
        cin >> a[i];
    int res = INT_MAX;
    for( int l = 1 , r = 0 , f = 0; l <= n ; l ++ ){
        while( r+1 <= n && f == 0 ){
            r ++ , vis[a[r]] ++;
            if( vis[a[r]] == 2 ) f = 1;
        }
        if( f == 0 ) break;
        res = min( res , r-l+1);
        vis[ a[l] ] --;
        if( vis[a[l]] == 1 ) f = 0;
    }
    if( res == INT_MAX ) res = -1;
    cout << res << "\n";
    return ;
}

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

D. Yet Another Monster Killing Problem

维护相同体力下,英雄的最大攻击力。并且体力更小的可以被体力更大的覆盖,因此还可以求一个后缀最大值。

这样的话就可以用一个快慢指针的形式\(O(n)\)的贪心一下,每次在满足可以覆盖当前怪兽的情况下,尽可能的选择体力更好的。

#include <bits/stdc++.h>

using namespace std;

void solve() {
    int n, m;
    cin >> n;
    vector<int> a(n), s(n + 1);
    for (auto &i: a)
        cin >> i;
    cin >> m;
    for (int i = 0, x, y; i < m; i++)
        cin >> x >> y, s[y] = max(s[y], x);
    for (int i = n - 1; i >= 0; i--)
        s[i] = max(s[i], s[i + 1]);
    int res = 0;
    for (int pos = 0, t, tp; pos < n;) {
        res++, t = pos, tp = a[t];
        while (t < n && tp <= s[t - pos + 1]) t++, tp = max(tp, a[t]);
        if (t == pos) {
            cout << "-1\n";
            return;
        }
        pos = t;
    }
    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. The Contest

dp,\(f[i][0/1/2]\)表示前\(i\)个数且第\(i\)个数在前缀中间后缀的最小交换次数。

\(f[i][j]\)可以从\(f[i-1][k]\)转移,条件是\(j\ge k\),代价是\(i\)是否原本在\(j\)

#include <bits/stdc++.h>

using namespace std;

#define int long long


int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n1, n2, n3, n;
    cin >> n1 >> n2 >> n3, n = n1 + n2 + n3;
    vector<int> a(n + 1);
    for (int i = 1, x; i <= n1; i++)
        cin >> x, a[x] = 0;
    for (int i = 1, x; i <= n2; i++)
        cin >> x, a[x] = 1;
    for (int i = 1, x; i <= n3; i++)
        cin >> x, a[x] = 2;
    vector<array<int, 3>> f(n + 1, {INT_MAX, INT_MAX, INT_MAX});
    f[0][0] = f[0][1] = f[0][2] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= 2; j++)
            for (int k = 0; k <= j; k++)
                f[i][j] = min(f[i][j], f[i - 1][k] + (a[i] != j));
    }
    cout << min({f[n][0], f[n][1], f[n][2]});
    return 0;
}

F. Make Them Similar

首先把所有是数字分成\(a_i,b_i\)两个部分,然后枚举数字\(x\),记\(c_i,d_i\)分别是\(a_i,b_i\)异或\(x\)后1 的数量,如果\(x\)满足则有\(c_1+d_1=c_i+d_i\),可以整理为\(c1-c_i=d_i-d_1\)。这样我们可以像枚举高十五位,用 map 统计所有的答案,然后再枚举低十五位,直接在map里面检查答案是否存在即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int M = (1 << 15) - 1;

#define lowbit(x) ( x & -x )

int cnt(int x) {
    int ans = 0;
    while (x) ans++, x -= lowbit(x);
    return ans;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n), b(n);
    for (int i = 0, x; i < n; i++)
        cin >> x, a[i] = x & M, b[i] = x >> 15;
    map<vector<int> , int> vis;
    for (int i = 0, t; i <= M; i++) {
        t = cnt(i ^ a[0]);
        vector<int> v;
        for (int j = 1; j < n; j++)
            v.push_back(t - cnt(i ^ a[j]));
        vis[v] = i;
    }
    for( int i = 0 , t ; i <= M ; i ++ ){
        t = cnt( i ^ b[0] );
        vector<int> v;
        for( int j = 1 ; j < n; j ++ )
            v.push_back( cnt( i ^ b[j]) - t);
        if( vis.count(v) ){
            cout << ((i<<15) | vis[v]) << "\n";
            return 0;
        }
    }
    cout << "-1\n";
    return 0;
}
posted @ 2023-07-28 15:52  PHarr  阅读(5)  评论(0编辑  收藏  举报