Codeforces Round #844(Div. 1 + Div. 2) 赛后补题
A.Parallel Projection
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>
#define LL long long
const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 2e5 + 10, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second
int T;
int w, d, h;
int a, b, f, g;//(a,b),(f,g)
int solve1() {//往左
int ans = 0;
ans = f + h + a + abs(b - g);
return ans;
}
int solve2() {//往右
int ans = 0;
ans = (w - f) + h + (w - a) + abs(b - g);
return ans;
}
int solve3() {//往下
int ans = 0;
ans = g + h + b + abs(a - f);
return ans;
}
int solve4() {
int ans = 0;
ans = (d - g) + h + (d - b) + abs(a - f);
return ans;
}
void solve() {
cin >> w >> d >> h;
cin >> a >> b >> f >> g;
int ans = 0;
ans = min(min(min(solve1(), solve2()), solve3()), solve4());
printf("%d\n", ans);
}
signed main() {
IOS;
cin >> T;
while (T--) {
solve();
}
return 0;
}
B.Going to the Cinema
排序,对于\(a[i]\),如果前\(i-1\)个人人数大于等于\(a[i]\)就加上,同时判断加上第\(i\)个人会不会对第\(i+1\)个人产生影响。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>
#define LL long long
const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 2e5 + 10, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second
int T;
void solve() {
int a[N];
int n;
int ans = 0;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + 1 + n);
ans = a[1] == 0 ? 1 : 2;
for (int i = 1; i < n; i++) {
if (i - 1 >= a[i] && i < a[i + 1]) ans++;
}
printf("%d\n", ans);
}
signed main() {
IOS;
cin >> T;
while (T--) {
solve();
}
return 0;
}
C. Equal Frequencies
参考@cup-pyy
问题1:设目标字符串共有\(x\)种字符,那么每种字符的个数就是\(\frac{n}{x}\)。统计原字符串每个字符的频数,并加入大根堆中。
枚举\(x\),对于前\(x\)种字符,判断每种字符的个数是否超过\(\frac{n}{x}\):超过部分计入答案;对于剩余\(n-x\)种字符,需要直接计入答案。
问题2:维护两个\(vector\):\(vector1\)保存上述两种情况字符对应的下标(用于修改),\(vector2\)保存需要补足数量的字符。对于\(vector1\)的每个下标,更改为需要补足数量的字符。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>
#define LL long long
const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 2e5 + 10, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second
int T;
void solve() {
int n, f = -1;
string s;
cin >> n >> s;
vector<PII > v;
int ans = n + 1;
map<int, vector<int> > m;
for (int i = 0; i < s.length(); i++) {
m[s[i] - 'a'].push_back(i);
}
for (int i = 0; i < 26; i++) {
if (m[i].size() == 0) v.push_back({0, i});
else v.push_back({m[i].size(), i});
}
sort(v.begin(), v.end(), greater<PII >());
for (int i = 1; i <= 26; i++) {
if (n % i) continue;
int sum = 0;
int x = n / i;
for (int j = 0; j < i; j++)
if (v[j].first > x) sum += v[j].first - x;
for (int j = i; j < 26; j++)
sum += v[j].first;
if (sum < ans) {
ans = sum;
f = i;
}
}
cout << ans << endl;
int sum = n / f;
vector<int> v1;
vector<int> v2;//如果超过,则将对应下标记录,将其加入到未超过的之中。
for (int i = 0; i < f; i++) {//前f种
if (v[i].first > sum) {
for (int j = 0; j < v[i].first - sum; j++)
v1.push_back(m[v[i].second][j]);//把超过种数的每个下标记录下来
}
if (v[i].first < sum) {
for (int j = 0; j < sum - v[i].first; j++)//补足
v2.push_back(v[i].second);
}
}
for (int i = f; i < 26; i++) {//对于剩余种数,如果出现在字符中,直接将其视为超过种数的
if (m[v[i].second].size() == 0) continue;
for (auto j: m[v[i].second])
v1.push_back(j);
}
for (int i = 0; i < ans; i++)
s[v1[i]] = (char) (v2[i] + 'a');
cout << s << endl;
return;
}
int main() {
IOS;
cin >> T;
while (T--) {
solve();
}
return 0;
}
D.Many Perfect Squares
设两个完全平方数分别为\(A^2,B^2\)可以被如下表示:\(a_i+x=A^2,a_j+x=B^2(i>j)\)
相减:\(a_i-a_j=(A+B)(A-B)\)
此时枚举\(x\)变为枚举前\(\sqrt x\)因子:
令\(v=A+B,u=A-B\),枚举\(u\),可解得\(A=(u+v)/2,B=(v-u)/2\),代入\(x=A^2-a_i\)。
对于每一个\(x\),暴力求出完全平方数个数再判断即可。
\(O(n^3 \sqrt x)\),尝试继续优化:
设\(dp_{i,A}\)为\(\{i,A\}\)时的方案数,通过\(\{j,B\}\)转移到\(\{i,A\}\)即可。
\(O(n^2 \sqrt x)\)
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>
#define LL long long
const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 100, M = 1e8, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second
int T;
void solve() {
int n, a[N];
map<LL, int> dp[N];
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
int ans = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j < i; j++) {
LL t = a[i] - a[j];
for (LL x = 1; x <= sqrt(t); x++) {
if (t % x) continue;
LL y = t / x;
if ((x + y) & 1LL || (y - x) & 1LL) continue;
LL A = (x + y) >> 1LL, B = (y - x) >> 1LL;
if (A * A < a[i] || B * B < a[j]) continue;
if (dp[j][B]) dp[i][A] = max(dp[i][A], dp[j][B] + 1);
else dp[i][A] = max(dp[i][A], 2);
ans = max(ans, dp[i][A]);
}
}
}
cout << ans << endl;
}
signed main() {
IOS;
cin >> T;
while (T--) {
solve();
}
return 0;
}

浙公网安备 33010602011771号