1. 程式人生 > 實用技巧 >Educational Codeforces Round 91 (Rated for Div. 2) ABCD

Educational Codeforces Round 91 (Rated for Div. 2) ABCD

A. Three Indices

如果存在一組解$a_i<a_j>a_k$,我們考察$a_{j-1},a_j,a_{j+1}$是否構成一組解,若不滿足,則再考察$a_{j-1}$或$a_{j+1}$,直到邊界$a_i,a_k$。於是如果序列有解,必然存在一組解$a_{j-1}<a_j>a_{j+1}$,$O(n)$掃描一遍就可以了。

B. Universal Solution

分別計算每一個$C_i$對win(1)+win(2)+⋯win(n)的貢獻值,發現最大貢獻值對應贏下S串中出現最多次數的操作,$O(n)$掃描即可。

C. Create The Teams

容易通過反證發現,優先把$a_i$高的編入隊中可得到最優解。

D. Berserk And Fireball

佇列中的戰士互不相同且無法改變順序,則可以$O(n)$在$a$中依次標記出所有$b$中元素,若無法標記則輸出$-1$。然後在$a$中就分割出了需要刪除的小區間,分類討論如何刪除最優。若區間長度$num<k$,需要考慮使用Berserk能否全部刪除;若區間長度$num>=k$,首先一定能通過Berserk將區間刪除至$k$倍$num$,然後判斷Berserk是否比Fireball操作更優,若Berserk更優,是否能使用Berserk全部刪除。注意細節模擬即可。

#include<cstdio>
#include<cstring>
#include
<algorithm> using namespace std; int p[1010]; int main() { int T; scanf("%d", &T); while (T--) { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &p[i]); bool flag = false; for (int i = 2; i < n; i++) {
if (p[i] > p[i - 1] && p[i] > p[i + 1]) { flag = true; puts("YES"); printf("%d %d %d\n", i - 1, i, i + 1); break; } } if (!flag) puts("NO"); } return 0; }

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[200010];
int cnt[300];
int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        cnt['R'] = 0;
        cnt['P'] = 0;
        cnt['S'] = 0;
        scanf("%s", s + 1);
        int len = strlen(s + 1);
        for (int i = 1; i <= len; i++) cnt[s[i]]++;
        int ans = cnt['R'];
        ans = max(ans, max(cnt['P'], cnt['S']));
        if (ans == cnt['R']) {
            for (int i = 1; i <= len; i++) putchar('P');
        }
        else {
            if (ans == cnt['P']) for (int i = 1; i <= len; i++) putchar('S');
            else for (int i = 1; i <= len; i++) putchar('R');
        }
        putchar('\n');
    }
    return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100010];
int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, x;
        scanf("%d%d", &n, &x);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        sort(a + 1, a + n + 1);
        int cnt = 1, ans = 0;
        for (int i = n; i >= 1; i--) {
            if (cnt * a[i] >= x) {
                ans++;
                cnt = 1;
            }
            else cnt++;
        }
        printf("%d\n", ans);
    }
    return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int a[200010], b[200010];
int ne[200010];
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    ll x, y, k;
    scanf("%lld%lld%lld", &x, &k, &y);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for (int i = 1; i <= m; i++) scanf("%d", &b[i]);
    int pos = 1, la = 0;
    for (int i = 1; i <= n; i++) {
        if (a[i] == b[pos]) {
            ne[la] = i;
            la = i;
            pos++;
        }
    }
    if (pos <= m) {
        puts("-1");
        return 0;
    }
    int end = la, num, cnt;
    ll ans = 0;
    num = ne[0] - 1;
    if (num < k) {
        for (int i = 1; i < ne[0]; i++) {
            if (a[i] > a[ne[0]]) {
                puts("-1");
                return 0;
            }
        }
        ans += (ll)num * y;
    }
    else {
        if (k * y < x) {
            bool flag = true;
            for (int i = 1; i < ne[0]; i++) {
                if (a[i] > a[ne[0]]) {
                    flag = false;
                    break;
                }
            }
            if (flag) ans += (ll)num * y;
            else ans += x + (ll)(num - k) * y;
        }
        else {
            ans += (ll)num / k * x;
            num %= k;
            ans += (ll)num * y;
        }
    }
    for (int i = ne[0]; i != end; i = ne[i]) {
        num = ne[i] - i - 1;
        if (num < k) {
            for (int j = i + 1; j < ne[i]; j++) {
                if (a[j] > a[i] && a[j] > a[ne[i]]) {
                    puts("-1");
                    return 0;
                }
            }
            ans += (ll)num * y;
        }
        else {
            if (k * y < x) {
                bool flag = true;
                for (int j = i + 1; j < ne[i]; j++) {
                    if (a[j] > a[i] && a[j] > a[ne[i]]) {
                        flag = false;
                        break;
                    }
                }
                if (flag) ans += (ll)num * y;
                else ans += x + (ll)(num - k) * y;
            }
            else {
                ans += (ll)num / k * x;
                num %= k;
                ans += (ll)num * y;
            }
        }
    }
    num = n - end;
    if (num < k) {
        for (int i = end + 1; i <= n; i++) {
            if (a[end] < a[i]) {
                puts("-1");
                return 0;
            }
        }
        ans += (ll)num * y;
    }
    else {
        if (k * y < x) {
            bool flag = true;
            for (int i = end + 1; i <= n; i++) {
                if (a[end] < a[i]) {
                    flag = false;
                    break;
                }
            }
            if (flag) ans += (ll)num * y;
            else ans += x + (ll)(num - k) * y;
        }
        else {
            ans += (ll)num / k * x;
            num %= k;
            ans += (ll)num * y;
        }
    }
    printf("%lld\n", ans);
    return 0;
}