VP Educational Codeforces Round 24
A. Diplomas and Certificates
点击查看代码
void solve() {
i64 n, k;
std::cin >> n >> k;
i64 cnt = (n / 2) / (k + 1) * k;
std::cout << cnt / k << " " << cnt << " " << n - cnt - cnt / k << "\n";
}
B. Permutation Game
题意:
可以通过
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> l(m + 1);
for (int i = 1; i <= m; ++ i) {
std::cin >> l[i];
}
std::vector<int> a(n + 1);
std::set<int> s;
for (int i = 1; i <= n; ++ i) {
s.insert(i);
}
for (int i = 1; i + 1 <= m; ++ i) {
int t = (l[i + 1] - l[i] + n) % n;
if (t == 0) {
t = n;
}
if (a[l[i]] == 0) {
if (!s.count(t)) {
std::cout << -1 << "\n";
return;
}
s.erase(t);
a[l[i]] = t;
} else if (a[l[i]] != t) {
std::cout << -1 << "\n";
return;
}
}
for (int i = 1; i <= n; ++ i) {
if (a[i] == 0) {
a[i] = *s.begin();
s.erase(s.begin());
}
}
for (int i = 1; i <= n; ++ i) {
std::cout << a[i] << " \n"[i == n];
}
}
C. Sofa Thief
题意:
求有没有一个沙发的左边有
给每个坐标从小到大从大到小排序模拟,求出每个沙发各个方向有多少沙发。
点击查看代码
void solve() {
int k, n, m, L, R, T, D;
std::cin >> k >> n >> m;
std::vector<std::array<int, 3>> a;
for (int i = 0; i < k; ++ i) {
int x1, y1, x2, y2;
std::cin >> x1 >> y1 >> x2 >> y2;
a.push_back({x1, y1, i});
a.push_back({x2, y2, i});
}
std::cin >> L >> R >> T >> D;
std::vector<int> l(k, -1), r(k, -1), t(k, -1), d(k, -1);
std::sort(a.begin(), a.end());
std::set<int> s;
for (int i = 0; i < a.size(); ++ i) {
int j = i;
while (j + 1 < a.size() && a[j + 1][0] == a[i][0]) {
++ j;
}
for (int x = i; x <= j; ++ x) {
l[a[x][2]] = (int)s.size() - s.count(a[x][2]);
}
for (int x = i; x <= j; ++ x) {
s.insert(a[x][2]);
}
i = j;
}
s.clear();
std::sort(a.begin(), a.end(), std::greater<>());
for (int i = 0; i < a.size(); ++ i) {
int j = i;
while (j + 1 < a.size() && a[j + 1][0] == a[i][0]) {
++ j;
}
for (int x = i; x <= j; ++ x) {
r[a[x][2]] = (int)s.size() - s.count(a[x][2]);
}
for (int x = i; x <= j; ++ x) {
s.insert(a[x][2]);
}
i = j;
}
s.clear();
std::sort(a.begin(), a.end(), [&](std::array<int, 3> & a, std::array<int, 3> & b) {
return a[1] > b[1];
});
for (int i = 0; i < a.size(); ++ i) {
int j = i;
while (j + 1 < a.size() && a[j + 1][1] == a[i][1]) {
++ j;
}
for (int x = i; x <= j; ++ x) {
d[a[x][2]] = (int)s.size() - s.count(a[x][2]);
}
for (int x = i; x <= j; ++ x) {
s.insert(a[x][2]);
}
i = j;
}
s.clear();
std::sort(a.begin(), a.end(), [&](std::array<int, 3> & a, std::array<int, 3> & b) {
return a[1] < b[1];
});
for (int i = 0; i < a.size(); ++ i) {
int j = i;
while (j + 1 < a.size() && a[j + 1][1] == a[i][1]) {
++ j;
}
for (int x = i; x <= j; ++ x) {
t[a[x][2]] = (int)s.size() - s.count(a[x][2]);
}
for (int x = i; x <= j; ++ x) {
s.insert(a[x][2]);
}
i = j;
}
s.clear();
for (int i = 0; i < k; ++ i) {
// std::cout << l[i] << " " << r[i] << " " << t[i] << " " << d[i] << "\n";
if (l[i] == L && r[i] == R && t[i] == T && d[i] == D) {
std::cout << i + 1 << "\n";
return;
}
}
std::cout << -1 << "\n";
}
D. Multicolored Cars
题意:有一个数组,
用
点击查看代码
void solve() {
int n, A;
std::cin >> n >> A;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::set<std::pair<int, int>> s;
for (int i = 1; i <= 1000000; ++ i) {
s.insert({0, i});
}
std::vector<int> cnt(1000010);
for (auto & c : a) {
if (s.count({cnt[c], c})) {
s.erase({cnt[c], c});
++ cnt[c];
s.insert({cnt[c], c});
}
auto it = s.lower_bound({cnt[A], 0});
s.erase(s.begin(), it);
}
s.erase({cnt[A], A});
if (s.empty()) {
std::cout << -1 << "\n";
} else {
std::cout << s.begin()->second << "\n";
}
}
E. Card Game Again
题意:求有多少区间的乘积和是
对
点击查看代码
void solve() {
int n, k;
std::cin >> n >> k;
std::vector<int> a(n + 1);
for (int i = 1; i <= n; ++ i) {
std::cin >> a[i];
}
std::map<int, int> mp;
for (int i = 2; i <= k / i; ++ i) {
if (k % i == 0) {
while (k % i == 0) {
++ mp[i];
k /= i;
}
}
}
if (k > 1) {
++ mp[k];
}
std::vector<int> sumk;
std::vector<int> b;
for (auto & [x, cnt] : mp) {
b.push_back(x);
sumk.push_back(cnt);
}
int m = (int)b.size();
std::vector sum(n + 1, std::vector<int>(m));
for (int i = 1; i <= n; ++ i) {
sum[i] = sum[i - 1];
for (int j = 0; j < m; ++ j) {
int cnt = 0;
while (a[i] % b[j] == 0) {
++ cnt;
a[i] /= b[j];
}
sum[i][j] += cnt;
}
}
auto check = [&](int l, int r) -> bool {
for (int i = 0; i < m; ++ i) {
if (sum[r][i] - sum[l - 1][i] < sumk[i]) {
return false;
}
}
return true;
};
i64 ans = 0;
for (int i = 1; i <= n; ++ i) {
int l = 1, r = i;
while (l < r) {
int mid = l + r + 1 >> 1;
if (check(mid, i)) {
l = mid;
} else {
r = mid - 1;
}
}
if (!check(l, i)) {
l = 0;
}
ans += l;
}
std::cout << ans << "\n";
}
F. Level Generation
题意:给你
我们肯定是先用
点击查看代码
void solve() {
i64 n;
std::cin >> n;
auto check = [&](i64 m) -> bool {
i64 cnt = (m + 1) / 2;
return (n - cnt) * (n - cnt - 1) / 2 >= m - cnt;
};
if (n == 1) {
std::cout << 0 << "\n";
return;
}
i64 l = 1, r = 2 * n;
while (l < r) {
i64 mid = l + r + 1 >> 1ll;
if (check(mid)) {
l = mid;
} else {
r = mid - 1;
}
}
std::cout << l << "\n";
}
G. Four Melodies
题意:在一个数组种选四个不相交的子序列,每个子序列相邻的两个数要么相差1,要么余7相同。使得四个子序列长度加起来最大。
本质是在一个图里选
如果我们向每个
我们可以对于每个
这个问题可以由
点击查看代码
template<class T>
struct MinCostFlow {
struct _Edge {
int to;
T cap;
T cost;
_Edge(int to_, T cap_, T cost_) : to(to_), cap(cap_), cost(cost_) {}
};
int n;
std::vector<_Edge> e;
std::vector<std::vector<int>> g;
std::vector<T> h, dis;
std::vector<int> pre;
bool dijkstra(int s, int t) {
dis.assign(n, std::numeric_limits<T>::max());
pre.assign(n, -1);
std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int>>, std::greater<std::pair<T, int>>> que;
dis[s] = 0;
que.emplace(0, s);
while (!que.empty()) {
T d = que.top().first;
int u = que.top().second;
que.pop();
if (dis[u] != d) {
continue;
}
for (int i : g[u]) {
int v = e[i].to;
T cap = e[i].cap;
T cost = e[i].cost;
if (cap > 0 && dis[v] > d + h[u] - h[v] + cost) {
dis[v] = d + h[u] - h[v] + cost;
pre[v] = i;
que.emplace(dis[v], v);
}
}
}
return dis[t] != std::numeric_limits<T>::max();
}
MinCostFlow() {}
MinCostFlow(int n_) {
init(n_);
}
void init(int n_) {
n = n_;
e.clear();
g.assign(n, {});
}
void addEdge(int u, int v, T cap, T cost) {
g[u].push_back(e.size());
e.emplace_back(v, cap, cost);
g[v].push_back(e.size());
e.emplace_back(u, 0, -cost);
}
std::pair<T, T> flow(int s, int t) {
T flow = 0;
T cost = 0;
h.assign(n, 0);
while (dijkstra(s, t)) {
for (int i = 0; i < n; ++i) {
h[i] += dis[i];
}
T aug = std::numeric_limits<int>::max();
for (int i = t; i != s; i = e[pre[i] ^ 1].to) {
aug = std::min(aug, e[pre[i]].cap);
}
for (int i = t; i != s; i = e[pre[i] ^ 1].to) {
e[pre[i]].cap -= aug;
e[pre[i] ^ 1].cap += aug;
}
flow += aug;
cost += aug * h[t];
}
return std::make_pair(flow, cost);
}
struct Edge {
int from;
int to;
T cap;
T cost;
T flow;
};
std::vector<Edge> edges() {
std::vector<Edge> a;
for (int i = 0; i < e.size(); i += 2) {
Edge x;
x.from = e[i + 1].to;
x.to = e[i].to;
x.cap = e[i].cap + e[i + 1].cap;
x.cost = e[i].cost;
x.flow = e[i + 1].cap;
a.push_back(x);
}
return a;
}
};
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
MinCostFlow<int> mf(2 * n + 4);
int s = 2 * n, t = 2 * n + 1, S = 2 * n + 2, T = 2 * n + 3;
mf.addEdge(S, s, 4, 0);
mf.addEdge(t, T, 4, 0);
for (int i = 0; i < n; ++ i) {
mf.addEdge(s, i, 1, 0);
mf.addEdge(i + n, t, 1, 0);
mf.addEdge(i, i + n, 1, -1);
for (int j = i + 1; j < n; ++ j) {
if (a[i] == a[j] + 1) {
mf.addEdge(i + n, j, 1, 0);
break;
}
}
for (int j = i + 1; j < n; ++ j) {
if (a[i] == a[j] - 1) {
mf.addEdge(i + n, j, 1, 0);
break;
}
}
for (int j = i + 1; j < n; ++ j) {
if (a[i] % 7 == a[j] % 7) {
mf.addEdge(i + n, j, 1, 0);
mf.addEdge(i, j, 1, 0);
break;
}
}
}
std::cout << -mf.flow(S, T).second << "\n";
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】