結果

問題 No.2553 Holidays
ユーザー InTheBloomInTheBloom
提出日時 2023-11-21 16:33:47
言語 D
(dmd 2.106.1)
結果
AC  
実行時間 6 ms / 2,000 ms
コード長 4,129 bytes
コンパイル時間 5,160 ms
コンパイル使用メモリ 189,904 KB
実行使用メモリ 5,376 KB
最終ジャッジ日時 2024-09-26 10:20:23
合計ジャッジ時間 3,063 ms
ジャッジサーバーID
(参考情報)
judge3 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 4 ms
5,248 KB
testcase_01 AC 5 ms
5,376 KB
testcase_02 AC 5 ms
5,376 KB
testcase_03 AC 5 ms
5,376 KB
testcase_04 AC 3 ms
5,376 KB
testcase_05 AC 2 ms
5,376 KB
testcase_06 AC 1 ms
5,376 KB
testcase_07 AC 2 ms
5,376 KB
testcase_08 AC 2 ms
5,376 KB
testcase_09 AC 2 ms
5,376 KB
testcase_10 AC 6 ms
5,376 KB
testcase_11 AC 4 ms
5,376 KB
testcase_12 AC 4 ms
5,376 KB
testcase_13 AC 6 ms
5,376 KB
testcase_14 AC 6 ms
5,376 KB
testcase_15 AC 2 ms
5,376 KB
testcase_16 AC 5 ms
5,376 KB
testcase_17 AC 2 ms
5,376 KB
testcase_18 AC 2 ms
5,376 KB
testcase_19 AC 4 ms
5,376 KB
testcase_20 AC 4 ms
5,376 KB
testcase_21 AC 3 ms
5,376 KB
testcase_22 AC 3 ms
5,376 KB
testcase_23 AC 2 ms
5,376 KB
testcase_24 AC 3 ms
5,376 KB
testcase_25 AC 3 ms
5,376 KB
testcase_26 AC 3 ms
5,376 KB
testcase_27 AC 3 ms
5,376 KB
testcase_28 AC 2 ms
5,376 KB
testcase_29 AC 3 ms
5,376 KB
testcase_30 AC 1 ms
5,376 KB
testcase_31 AC 1 ms
5,376 KB
testcase_32 AC 1 ms
5,376 KB
testcase_33 AC 1 ms
5,376 KB
testcase_34 AC 1 ms
5,376 KB
testcase_35 AC 1 ms
5,376 KB
testcase_36 AC 1 ms
5,376 KB
testcase_37 AC 2 ms
5,376 KB
testcase_38 AC 1 ms
5,376 KB
testcase_39 AC 1 ms
5,376 KB
testcase_40 AC 1 ms
5,376 KB
testcase_41 AC 1 ms
5,376 KB
testcase_42 AC 1 ms
5,376 KB
testcase_43 AC 1 ms
5,376 KB
testcase_44 AC 2 ms
5,376 KB
testcase_45 AC 1 ms
5,376 KB
testcase_46 AC 1 ms
5,376 KB
testcase_47 AC 1 ms
5,376 KB
testcase_48 AC 1 ms
5,376 KB
testcase_49 AC 1 ms
5,376 KB
testcase_50 AC 1 ms
5,376 KB
testcase_51 AC 1 ms
5,376 KB
testcase_52 AC 1 ms
5,376 KB
testcase_53 AC 1 ms
5,376 KB
testcase_54 AC 1 ms
5,376 KB
testcase_55 AC 1 ms
5,376 KB
testcase_56 AC 1 ms
5,376 KB
testcase_57 AC 2 ms
5,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import std;

void main () {
    int N, M; readln.read(N, M);
    string S = readln.chomp;

    solve(N, M, S);
}

void solve (int N, int M, string S) {
    /*
       'x'や'o'のあるところで区切って良い。本質的に、区切られた文字は3種類のみ
       1. x --- x
       2. x --- o
       3. o --- o
       このうち、最も優先すべきはタイプ3で、かつ-の長さが奇数のもの。これは最高効率で埋めることができる可能性がある。
       次に優先度が高いのが長さ2以上の2と、3かつ-の長さが偶数のもの。これらは確実に1個で2つの祝日を生み出せる。
       次に優先度が高いのが長さ3以上の1
       一番優先度が低いのが長さ2以下の1と長さ1の2

       これらを守って処理すれば必ず最高効率になるはず
       ↑間違っていた。タイプ3で長さが奇数のものは短いものから潰すべき
     */

    /* 区間分割 */
    auto T = new BinaryHeap!(Array!int, "a<b")[](3);
    BinaryHeap!(Array!int, "a>b") T2;
    int l = 0;
    int r = 0;

    while (true) {
        if (S.length <= l) break;
        if (S[l] == '-') {
            int type = 0;
            r = l;
            if (0 < r && S[r-1] == 'o') type++;
            while (true) {
                if (r == S.length || S[r] == 'x') {
                    break;
                }
                if (S[r] == 'o') {
                    type++;
                    break;
                }
                r++;
            }
            if (type == 2 && (r-l) % 2 == 1) T2.insert(r-l);
            else T[type].insert(r-l);
            l = r;
        }
        l++;
    }

    int ans = 0;
    foreach (c; S) if (c == 'o') ans++;

    /* 処理 */
    while (0 < M || !T2.empty) {
        // dbg
        /*
        foreach (t; T) writeln(t.dup);
        writeln("ans: ", ans);
        writeln("M: ", M);
        writeln("");
        */

        if (!T2.empty) {
            auto head = T2.front; T2.removeFront;
            if (head == 1) { ans++; continue; }
            if (head/2 <= M) {
                ans += head;
                M -= head/2;
            }
            else {
                ans += 2*M;
                M = 0;
            }
            continue;
        }

        if (!T[2].empty) {
            auto head = T[2].front; T[2].removeFront;
            if (head/2 <= M) {
                ans += head;
                M -= head/2;
            }
            else {
                ans += 2*M;
                M = 0;
            }
            continue;
        }

        if (!T[1].empty && 2 <= T[1].front) {
            auto head = T[1].front; T[1].removeFront;
            if (head/2 <= M) {
                ans += 2*(head/2);
                M -= head/2;
                head -= 2*(head/2);
                if (0 < head) T[1].insert(head);
            }
            else {
                ans += 2*M;
                M = 0;
                head -= 2*M;
                if (0 < head) T[1].insert(head);
            }
            continue;
        }

        if (!T[0].empty && 3 <= T[0].front) {
            auto head = T[0].front; T[0].removeFront;
            ans++;
            M--;
            head--;
            T[1].insert(head);
            continue;
        }

        /* 優先度最悪 */
        if (!T[1].empty && T[1].front == 1) {
            auto head = T[1].front; T[1].removeFront;
            ans++;
            M--;
            continue;
        }

        if (!T[0].empty && T[0].front <= 2) {
            auto head = T[0].front; T[0].removeFront;
            if (head <= M) {
                ans += head;
                M -= head;
            }
            else {
                ans += M;
                head -= M;
                M = 0;
                if (0 < head) T[1].insert(head);
            }
            continue;
        }

        /* 何も選べない */
        break;
    }

    writeln(ans);
}

void read(T...)(string S, ref T args) {
    auto buf = S.split;
    foreach (i, ref arg; args) {
        arg = buf[i].to!(typeof(arg));
    }
}
0