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;
}