Codeforces Round #844 (Div. 1 + Div. 2, based on VK Cup 2022 - Elimination Round)

C. Equal Frequencies(贪心)

题目大意
给定一个由小写字母构成的字符串\(s\),若该字符串中所有字母出现次数相等,则称其为“平衡字符串”。
给定一个字符串\(s\),问将其修改为“平衡字符串”的最少操作(将一个字符修改为另一个字符)数,并输出修改后的字符串。

解题思路
枚举使用字符的种类数\(i\),贪心的在\(s\)中保留前\(i\)中出现次数最多的字符,并将多余的字符修改为需要的字符即可。

参考代码

#include <bits/stdc++.h>
using namespace std;
string s;
void work()
{

    int n;
    cin >> n;
    cin >> s;
    map<int, int> ch;//记录每种字母出现的次数
    int ans = 1e9, cnt_type = 0;
    for (int i = 0; i < n; ++i)
    {
        ++ch[s[i] - 'a'];
    }
    vector<pair<int, int>> chs;//排序
    for (int i = 0; i < 26; ++i)
    {
        chs.push_back({i, ch[i]});
    }
    sort(chs.begin(), chs.end(), [](pair<int,int> a, pair<int, int> b)
    {
        return a.second > b.second;
    });
    for (int i = 1; i <= 26; ++i)
    {
        if (n % i)
            continue;
        int tans = 0, t = n / i;
        for (int j = 0; j < i; ++j)
        {
            if (chs[j].second < t)
            tans += t - chs[j].second;
        }
        if (tans < ans)
        {
            ans = tans;
            cnt_type = i;
        }
    }
    int use[30] = {0};
    for (int i = 0; i < cnt_type; ++i)
    {
        use[chs[i].first] = 1;
    }
    for (auto &c : s)
    {
        int need = (use[c - 'a'] == 1 ? n / cnt_type : 0);
        if (ch[c - 'a'] > need)
        {
            for (int j = 0; j < cnt_type; ++j)
            {
                if (ch[chs[j].first] < n / cnt_type)
                {
                    ch[c - 'a']--;
                    ch[chs[j].first]++;
                    c = chs[j].first + 'a';
                }
            }
        } 
    }
    cout << ans << endl << s << endl;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;
    cin >> T;
    while (T--)
    {
        work();
    }
    return 0;
}

D. Many Perfect Squares(数论)

题目大意
给定一个数组\(a\),可以对\(a\)中的每一个元素都加\(x\),求使得新数组中完全平方数最多的\(x\)

解题思路
由于每个元素都加相同的值,故其差值不变。令\(a_i + x = p^2\)\(a_j + x = q^2\)\(d = p^2-q^2 = (p+q)(p-q)\)
枚举\(d\)的因子得到\(d=d_1*d_2\),那么有\(p=\frac{d_1+d_2}{2}\)\(q=\frac{d_1-d_2}{2}\)\(d_1\)\(d_2\)为整数需要\(p\)\(q\)同奇偶。然后对于每个\(x\)统计答案。

参考代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll a[100];
bool check(ll x)// 这里也可以手写二分
{
    ll t = sqrt(1.0 * x);
    return x == t * t;
}
void work()
{
    int n;
    cin >> n;
    int ans = 1;
    for (int i = 0; i < n; ++i)
    {
        cin >> a[i];
    }
    for (int i = 1; i < n; ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            ll d = a[i] - a[j];
            for (ll k = 1; k * k <= d; ++k)
            {
                if (d % k == 0)
                {
                    ll d1 = k, d2 = d / k;
                    if (d1 - d2 & 1)
                        continue;
                    ll t = d1 + d2 >> 1;
                    ll x = t * t - a[i];
                    if (x >= 0)
                    {
                        int tans = 0;
                        for (int c = 0; c < n; ++c)
                        {
                            if (check(a[c] + x))
                                ++tans;
                        }
                        ans = max(ans, tans);
                    }
                }
            }
        }
    }
    cout << ans << endl;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;
    cin >> T;
    while (T--)
    {
        work();
    }
    return 0;
}
posted @ 2023-01-17 15:58  何太狼  阅读(30)  评论(0编辑  收藏  举报