Educational Codeforces Round 122 (Rated for Div. 2)

A. Div. 7

#include<bits/stdc++.h>

using namespace std;

void solve(){
    int n , a , b , c ;
    cin >> n;
    c = n % 10 , n /= 10;
    b = n % 10 , n /= 10;
    a = n % 10 , n /= 10;
    int res , val = 100;
    for( int i = 0 ; i <= 9 ; i ++ ){
        if( a != 0 and i == 0 ) continue;
        if( a == 0 and i != 0 ) continue;
        for( int j = 0 ; j <= 9 ; j ++ ){
            if( a == 0 and j == 0 ) continue;
            for( int k = 0 , x , y ; k <= 9 ; k ++ ){
                x = i * 100 + j * 10 + k;
                if( x % 7 != 0 ) continue;
                y = ( i != a ) + ( j != b ) + ( k != c );
                if( y < val  ) val = y , res = x;
            }
        }
    }
    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;
}

B. Minority

选整个序列操作可能对最优,如果01数量相同,少选一位就好了。

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;


void solve() {
    string s;
    cin >> s;
    int a = 0, b = 0;
    for (auto i: s)
        if (i == '0') a++;
        else b++;
    if( a == b ) cout << a - 1 << "\n";
    else cout << min( a , b ) << "\n";
    return;
}

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

C. Kill the Monster

\(k\)不大,直接枚举出增加生命值的次数,然后\(O(1)\)计算出双发把对方击败所需要的次数

#include<bits/stdc++.h>

using namespace std;

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

void solve() {
    int hc, dc, hm, dm, k, w, a;
    cin >> hc >> dc >> hm >> dm >> k >> w >> a;

    for( int i = 0 , x , y ; i <= k ; i ++ ){
        x = ( hc + i * a + dm - 1 ) / dm;
        y = ( hm + dc + ( k - i) * w - 1 ) / ( dc + ( k - i) * w );
        if( x >= y ){
            cout << "YES\n";
            return ;
        }
    }
    cout << "NO\n";
    return;
}

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

D. Make Them Equal

预处理出从\(1\)向后转移所需要的最小次数。然后每次统计一下答案就好了。

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int inf = 1e18;

using vi = vector<int>;

const int N = 1e3;
vi val(N + 1, inf);

void solve() {
    int n, k;
    cin >> n >> k;
    vi b(n), c(n);
    for (auto &i: b) cin >> i, i = val[i];
    for (auto &i: c) cin >> i;
    k = min( k , accumulate(b.begin(), b.end(), 0ll));
    vi f(k + 1);
    for (int i = 0; i < n; i++) {
        for (int j = k; j >= b[i]; j--)
            f[j] = max(f[j], f[j - b[i]] + c[i]);
    }
    cout << *max_element(f.begin(), f.end()) << "\n";
    return;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    val[1] = 0;
    for (int i = 1; i <= N; i++) {
        for (int j = 1, t; j <= i; j++) {
            t = i / j;
            if (i + t > N) continue;
            val[i + t] = min(val[i + t], val[i] + 1);
            if (t == 1) break;
        }
    }
    int t;
    for (cin >> t; t; t--)
        solve();
    return 0;
}
posted @ 2023-09-30 12:36  PHarr  阅读(10)  评论(0编辑  收藏  举报