VP Codeforces Round 905 (Div. 2)
A. Chemistry
题意:一个字符串,能不能删除不超过
记录每个字符的数量,如果是奇数则我们可能需要删除,最多留一个不能删的放在中间。
点击查看代码
void solve() {
int n, k;
std::cin >> n >> k;
std::string s;
std::cin >> s;
std::vector<int> cnt(26);
for (auto & c : s) {
++ cnt[c - 'a'];
}
int tot = 0;
for (int i = 0; i < 26; ++ i) {
tot += cnt[i] & 1;
}
if (k - tot >= -1) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
}
B. Raspberries
题意:给你一个数组,每次可以给一个数加一,使得这些数的乘积是
发现除了
点击查看代码
void solve() {
int n, k;
std::cin >> n >> k;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
int ans = 1e9;
for (int i = 0; i < n; ++ i) {
ans = std::min(ans, (a[i] + k - 1) / k * k - a[i]);
}
if (k == 4) {
int min1 = 1e9, min2 = 1e9;
for (int i = 0; i < n; ++ i) {
int x = (a[i] + 1) / 2 * 2 - a[i];
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2) {
min2 = x;
}
}
std::cout << std::min(ans, min1 + min2) << "\n";
} else {
std::cout << ans << "\n";
}
}
C. You Are So Beautiful
题意:求数组有多少子数组在所有子序列里只出现过一次。
预处理每个数前面有没有出现过,和在后面有没有出现过。那么所选的子数组的第一个数和最后一个数在前后各自不能出现。从前往后枚举右端点,如果右端点合法则加上前面合法的左端点的个数。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::vector<int> pre(n), suf(n);
std::set<int> s;
for (int i = 0; i < n; ++ i) {
if (s.count(a[i])) {
pre[i] = 1;
}
s.insert(a[i]);
}
s.clear();
for (int i = n - 1; i >= 0; -- i) {
if (s.count(a[i])) {
suf[i] = 1;
}
s.insert(a[i]);
}
i64 ans = 1;
int sum = 0;
for (int i = 0; i < n; ++ i) {
sum += !pre[i];
if (!suf[i]) {
ans += i == n - 1 ? sum - 1 : sum;
}
}
std::cout << ans << "\n";
}
D1. Dances (Easy version) && D2. Dances (Hard Version)
题意:给你两个数组
因为可以重排,我们自然是让两个数组都从小到大排。然后
对于
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> a(n), b(n);
for (int i = 1; i < n; ++ i) {
std::cin >> a[i];
}
for (int i = 0; i < n; ++ i) {
std::cin >> b[i];
}
std::sort(b.begin(), b.end());
auto get = [&](int x) -> int {
auto aa = a;
aa[0] = x;
std::sort(aa.begin(), aa.end());
auto check = [&](int x) -> bool {
for (int i = 0; i < n - x; ++ i) {
if (aa[i] >= b[i + x]) {
return false;
}
}
return true;
};
int l = 0, r = n;
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
};
i64 ans = 0;
for (int i = 1; i <= m;) {
int l = i, r = m;
int t = get(i);
while (l < r) {
int mid = l + r + 1 >> 1;
if (t == get(mid)) {
l = mid;
} else {
r = mid - 1;
}
}
ans += (i64)(l - i + 1) * get(i);
// std::cout << get(i) << " " << i << " " << l << "\n";
i = l + 1;
}
std::cout << ans << "\n";
}
E. Time Travel
题意:有
对于第
点击查看代码
void solve() {
int n, t;
std::cin >> n >> t;
std::vector<std::vector<std::pair<int, int>>> adj(n);
for (int i = 0; i < t; ++ i) {
int m;
std::cin >> m;
while (m -- ) {
int u, v;
std::cin >> u >> v;
-- u, -- v;
adj[u].push_back({v, i});
adj[v].push_back({u, i});
}
}
int k;
std::cin >> k;
std::vector<std::vector<int>> pos(t);
for (int i = 0; i < k; ++ i) {
int x;
std::cin >> x;
-- x;
pos[x].push_back(i);
}
const int inf = 1e9;
using PII = std::pair<int, int>;
std::vector<int> dist(n, inf);
dist[0] = 0;
std::priority_queue<PII, std::vector<PII>, std::greater<PII>> heap;
heap.push({dist[0], 0});
while (heap.size()) {
auto [d, u] = heap.top(); heap.pop();
if (d != dist[u]) {
continue;
}
for (auto & [v, t] : adj[u]) {
auto it = std::lower_bound(pos[t].begin(), pos[t].end(), d);
if (it == pos[t].end()) {
continue;
}
if (dist[v] > *it + 1) {
dist[v] = *it + 1;
heap.push({dist[v], v});
}
}
}
int ans = dist[n - 1] == inf ? -1 : dist[n - 1];
std::cout << ans << "\n";
}
F. Minimum Array
题意:一个数组,
区间加可以联想到差分操作。我们用
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<i64> a(n + 1);
for (int i = 1; i <= n; ++ i) {
std::cin >> a[i];
}
int m;
std::cin >> m;
std::vector<int> l(m + 1), r(m + 1), x(m + 1);
int p = 0;
std::map<int, i64> d;
for (int i = 1; i <= m; ++ i) {
std::cin >> l[i] >> r[i] >> x[i];
d[l[i]] += x[i], d[r[i] + 1] -= x[i];
while (!d.empty() && d.begin()->second == 0) {
d.erase(d.begin());
}
if (!d.empty() && d.begin()->second < 0) {
p = i;
d.clear();
}
}
std::vector<i64> b(n + 2);
for (int i = 1; i <= p; ++ i) {
b[l[i]] += x[i]; b[r[i] + 1] -= x[i];
}
for (int i = 1; i <= n; ++ i) {
b[i] += b[i - 1];
a[i] += b[i];
}
for (int i = 1; i <= n; ++ i) {
std::cout << a[i] << " \n"[i == n];
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】