Codeforces Round #734 (Div. 3) A~D1 個人題解


比賽鏈接:Here

1551A. Polycarp and Coins (簽到)

題意:

我們有任意個面額為 \(1\)\(2\) 的硬幣去支付 \(n\) 元賬單,

現在請問怎么去分配數額使得 \(c_1 +2 * c_2 = n\) 並且要最小化 \(|c_1-c_2|\)


貪心,

很容易想到最小化 \(|c_1 - c_2|\) 等於 \(0\)\(1\)

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int _; for (cin >> _; _--;) {
        int n;
        cin >> n;
        if (n % 3 == 0) cout << n / 3 << " " << n / 3 << "\n";
        else if (n % 3 == 1) cout << n / 3 + 1 << " " << n / 3 << "\n";
        else cout << n / 3 << " " << n / 3 + 1 << "\n";
    }
}

1551B1. Wonderful Coloring - 1(easy)

題意:

給定長度為 \(n\) 的字符串和 \(k = 2\) 種顏色,

對於字符串每一個位置要么不塗顏色,要么每種顏色的字母都要不同並且最后 \(k\) 種顏色塗的個數相同

請輸出每種顏色最后的個數


統計 26 個字母出現次數,然后出現超過 2 的+1,僅出現一次的個數 / 2即可(易證明)

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int _; for (cin >> _; _--;) {
        string s;
        cin >> s;
        int a[30] = {0};
        for (int i = 0; i < int(s.length()); ++i) {
            a[s[i] - 'a']++;
        }
        int a2 = 0, a1 = 0;
        for (int i = 0; i < 26; ++i) {
            if (a[i] == 1)a1++;
            if (a[i] > 1)a2++;
        }
        cout << a1 / 2 + a2 << "\n";
    }
}

1551B2. Wonderful Coloring - 2 (hard版本)

題意基本同 B1 一致,

但需輸出每個位置數字塗的顏色


寫了兩罰模擬 \(\mathcal{O}(n^2)\) 不出所料肯定 T了,

轉換一下思路,首先和 B1 一樣我們需要去統計每種數字的個數,但由於最后需要輸出每個位置的顏色編號,所以還得存一下下標 (pos)

  • \(cnt[a[i]] \le k\) 的將下標存儲
  • \(cnt[a[i]] > k\) 無需使用標 \(0\)

當然對於多余的元素,可以直接從刪除

while (pos.size() % k != 0)pos.pop_back();

此時 pos 中所有元素均為有效下標,我們只要對應原數組標記顏色編號即可

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int _; for (cin >> _; _--;) {
        int n, k;
        cin >> n >> k;
        vector<int>a(n), cnt(n);
        vector<int>pos;
        for (int i = 0; i < n; ++i) {
            cin >> a[i], a[i] -= 1;
            cnt[a[i]] += 1;
            if (cnt[a[i]] <= k) pos.push_back(i);
        }
        while (pos.size() % k != 0)pos.pop_back();
        sort(pos.begin(), pos.end(), [&](int i, int j) {return a[i] < a[j];});
        vector<int>ans(n);
        for (int i = 0; i < pos.size(); ++i)
            ans[pos[i]] = i % k + 1;
        for (int i = 0; i < n; ++i)
            cout << ans[i] << " \n"[i == n - 1];
    }
}

1551C. Interesting Story

題意:

一個作家有 \(n\) 個單詞,每一個單詞只會由 a,b,c,d,e 構成,他想用 \(m(0\le m\le n)\) 個單詞寫一個故事

一個故事是否有趣在於:

  • 故事中存在一個字母的個數比其他字母個數的總和還更多

    比如:bac,aaada,e 三個單詞,a 出現的次數比其他 4 種單詞出現次數都多

請輸出在保證故事有趣的情況下用更多的單詞寫故事


這里建議直接看代碼便於理解

【AC Code】代碼參考於比賽 高Rank dalao

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int _; for (cin >> _; _--;) {
        int n;
        cin >> n;
        vector<string>s(n);
        for (int i = 0; i < n; ++i) cin >> s[i];
        int ans = 0;
        for (int c = 0; c < 5; ++c) {
            vector<int>f(n);
            for (int i = 0; i < n; ++i) {
                for (auto x : s[i])
                    if (x == 'a' + c)f[i]++;
                    else f[i]--;
            }

            sort(f.begin(), f.end(), greater<int>());
            int sum  = 0;
            for (int i = 0; i < n; ++i) {
                sum += f[i];
                if (sum <= 0)break;
                ans = max(ans, i + 1);
            }
        }
        cout << ans << "\n";
    }
}

很好奇自己是怎么讀題讀成使用連續的單詞去寫故事的啊?kola

1551D1. Domino (easy version)

題意:待補


多米諾骨牌的排放似乎在ABC的某一場也出現過

如果 \(n\) 為奇數

  • 最少要橫放 \(m / 2\) 個,不然最少 \(0\)
  • 最多 \(n * m / 2 = (m \% 2 == 1 ?\ n / 2 : 0)\)

對於給出的 \(k\) 只要在 \([mn,mx]\) 就輸出 YES

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int _; for (cin >> _; _--;) {
        int n, m, k;
        cin >> n >> m >> k;

        int mn = (n % 2 == 1 ? m / 2 : 0);
        int mx = n * m / 2 - (m % 2 == 1 ? n / 2 : 0);
        if (mn <= k and k <= mx and (k - mn) % 2 == 0) cout << "YES\n";
        else cout << "NO\n";
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM