Codeforces Round 834 (Div. 3)

A. Yes-Yes?

#include <bits/stdc++.h>

using namespace std;

#define int long long
using pii = pair<int, int>;
using vi = vector<int>;

const string T = "Yes";

void solve() {
    string s;
    cin >> s;
    int i = -1;
    if( s[0] == 'Y' ) i = 0;
    else if( s[0] == 'e' ) i = 1;
    else if( s[0] == 's' ) i = 2;
    if( i == -1 ){
        cout << "NO\n";
        return ;
    }
    for( auto c : s ){
        if( c != T[i] ){
            cout << "NO\n";
            return ;
        }
        i = ( i + 1 ) % 3;
    }
    cout << "YES\n";
    return;
}

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

B. Lost Permutation

枚举序列的最大值

#include <bits/stdc++.h>

using namespace std;

#define int long long
using pii = pair<int, int>;
using vi = vector<int>;

void solve() {
    int m, s, b = 0;
    cin >> m >> s;
    for (int i = 1, x; i <= m; i++)
        cin >> x, b = max(b, x), s += x;
    while (b * (b + 1) / 2 < s) b++;
    cout << (b * (b + 1) / 2 == s ? "YES\n" : "NO\n");
    return;
}

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

C. Thermostat

情况数量不多

\[a=b\\ a\rightarrow b\\ a \rightarrow l \rightarrow b\\ a \rightarrow r \rightarrow b\\ a \rightarrow l \rightarrow r \rightarrow b\\ a \rightarrow r \rightarrow l \rightarrow b \]

逐个判断就好了

#include <bits/stdc++.h>

using namespace std;

#define int long long
using pii = pair<int, int>;
using vi = vector<int>;

void solve() {
    int l, r, a, b, x;
    cin >> l >> r >> x >> a >> b;

    bool ab = abs(a - b) >= x;
    bool al = abs(a - l) >= x;
    bool ar = abs(a - r) >= x;
    bool lr = abs(l - r) >= x;
    bool lb = abs(l - b) >= x;
    bool rb = abs(r - b) >= x;


    if (a == b)cout << "0\n";
    else if (ab) cout << "1\n";
    else if (al and lb) cout << "2\n";
    else if (ar and rb) cout << "2\n";
    else if (al and lr and rb) cout << "3\n";
    else if (ar and lr and lb) cout << "3\n";
    else cout << "-1\n";
    return;
}

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

D. Make It Round

对于一个数字\(x=2^a\times5^b\times c\),那么末尾0的数量就是\(\min(a,b)\)

所以我们枚举乘数中2 和5的次方数就好了

#include <bits/stdc++.h>

using namespace std;

#define int long long
using pii = pair<int, int>;
using vi = vector<int>;

void solve() {
    int n, m, res, cnt, a = 0, b = 0;
    cin >> n >> m;
    for (int t = n; t > 0 and t % 2 == 0; t /= 2, a++);
    for (int t = n; t > 0 and t % 5 == 0; t /= 5, b++);
    res = n, cnt = min(a, b);
    for (int i = 0, x = 1; x <= m; i++, x *= 2)
        for (int j = 0, y = 1; x * y <= m; j++, y *= 5) {
            int t = min(a + i, b + j), p = m / (x * y) * (x * y) * n;

            if (t == cnt and p > res) res = p;
            else if (t > cnt) cnt = t, res = p;
        }
    if (cnt == min(a, b)) res = n * m;
    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 Humanoid

使用药剂的顺序只有三种,三种顺序每种都贪心的取一下,最后取最优解即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long
using pii = pair<int, int>;
using vi = vector<int>;

int n, h;
vi a;

int ggb() {
    int i = 0, w = h;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    w *= 2;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    w *= 2;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    w *= 3;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    return i;
}

int gbg() {
    int i = 0, w = h;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    w *= 2;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    w *= 3;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    w *= 2;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    return i;
}

int bgg() {
    int i = 0, w = h;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    w *= 3;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    w *= 2;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    w *= 2;
    while (i < n and a[i] < w)
        w += a[i] / 2, i++;
    return i ;
}


void solve() {
    cin >> n >> h;
    a = vi(n);
    for (auto &i: a) cin >> i;
    sort(a.begin(), a.end());
    cout << max({ggb(), bgg(), gbg()}) << "\n";
    return;
}

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

F. All Possible Digits

其实我们只能对末尾进行操作,且只能加一。

末尾数字是\(pn\),我们只用考虑两种情况

  1. \([0,pn]\)中所有的数字都已经出现过了,我们只需要找到\((pn,p)\)中没出现过的最大值,然后加过去即可。
  2. \([0,pn]\)中所有的数字没有都出现过,首先一直加直到进位,此时\((pn,p)\)中所有的都已经出现过,当前末尾是0,找到\((0,pn)\)中没有出现过的最大值,加过去就好
#include <bits/stdc++.h>

using namespace std;

#define int long long
using pii = pair<int, int>;
using vi = vector<int>;

void solve() {
    int n, p;
    cin >> n >> p;
    vector<int> a(n);
    for (auto &i: a) cin >> i;
    int pn = a.back();
    auto b = a;
    sort(a.begin(), a.end());
    a.resize(unique(a.begin(), a.end()) - a.begin());
    if (pn < a.size() and a[pn] == pn) {
        p--;
        while (p == a.back() and p > pn)
            p--, a.pop_back();
        cout << p - pn << "\n";
    } else {
        reverse(b.begin(), b.end());
        int res = p - pn;
        b[0] = p;
        for (int i = 0; i < n - 1; i++) {
            if (b[i] < p) continue;
            b[i + 1] += b[i] / p, b[i] %= p;
        }

        for (int x; b.back() >= p;)
            x = b.back() / p, b.back() %= p, b.push_back(x);

        for (auto i: b)
            a.push_back(i);
        sort(a.begin(), a.end());
        a.resize(unique(a.begin(), a.end()) - a.begin());
        auto it = lower_bound(a.begin(), a.end(), pn);
        while (*it == pn and pn >= 0)
            it--, pn--;
        res += max(pn, 0ll);
        cout << res << "\n";
    }
    return;
}

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

G. Restore the Permutation

对于相邻的两个数,取最大值,所以一定是把当前所有数字放在偶数位上,然后在奇数位置放一个较小的数字。

首先我们判断时候有解。

我们把所有没有放置的数字存起来,然后正序操作,每次放置一个尽可能大的,如果不能全部放完,则无解。

然后找字典序最小的解,反序操作一遍即可。

然后其实发现,我们直接反序操作就行,放不完直接就可以判断出无解。

#include <bits/stdc++.h>

using namespace std;

#define int long long
using pii = pair<int, int>;
using vi = vector<int>;

void solve() {
    int n;
    cin >> n;
    vi vis(n + 1), res(n + 1);
    for (int i = 2; i <= n; i += 2)
        cin >> res[i], vis[res[i]]++;
    if (*max_element(vis.begin(), vis.end()) > 1) {
        cout << "-1\n";
        return;
    }
    set<int> a;
    for (int i = 1; i <= n; i++)
        if (vis[i] == 0) a.insert(i);
    for (int i = n; i >= 1; i -= 2) {
        auto it = a.lower_bound(res[i]);
        if (it == a.begin()) {
            cout << "-1\n";
            return;
        }
        it = prev(it), res[i - 1] = *it, a.erase(it);
    }
    for( int i = 1 ; i <= n ; i ++ )
        cout << res[i] << " ";
    cout << "\n";
    return;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}
posted @ 2023-10-10 16:56  PHarr  阅读(8)  评论(0编辑  收藏  举报