比赛链接:https://codeforces.com/contest/1408

A. Circle Coloring

题意

给出三个长为 $n$ 的序列 $a,b,c$,对于每个 $i$,$a_i \ne b_i,\ a_i \ne c_i,\ b_i \ne c_i$ 。

构造序列 $p$,使得:

  • $p_i \in \{a_i, b_i, c_i\}$
  • $p_i \neq p_{(i + 1 \mod n)}$

题解

即每个数不与前后两个数相同,因为三个序列同一位置两两不同,所以对于每个位置一定都有满足条件的数,枚举即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<vector<int>> vec(3, vector<int> (n));
for (auto &v : vec) {
for (auto &x : v) {
cin >> x;
}
}
vector<int> p(n);
for (int i = 0; i < n; i++) {
for (auto &v : vec) {
if (v[i] != p[(i - 1 + n) % n] and v[i] != p[(i + 1) % n]) {
p[i] = v[i];
break;
}
}
}
for (int i = 0; i < n; i++) {
cout << p[i] << " \n"[i == n - 1];
}
}
return 0;
}

B. Arrays Sum

题意

给出一个大小为 $n$ 的非递减序数组 $a$ 和一个正整数 $k$ 。

构造 $m$ 个非递减序数组 $b_1, b_2, \ldots, b_m$,要求:

  • 每个 $b_i$ 大小为 $n$
  • $a_i = b_{1, i} + b_{2, i} + \ldots + b_{m, i}$
  • 每个 $b_i$ 中最多有 $k$ 个不同的数

找出 $m$ 的最小值。

题解

设 $a$ 中有 $x$ 个不同的数,答案即 $1 + \lceil \frac{x - k}{k - 1} \rceil$ 。

因为 $b_1$ 可以包含 $a$ 中前 $k$ 个不同的数,之后的 $b_i$ 因为要用 $0$ 维护前面已有的和,每次只能新加 $a$ 中 $k-1$ 个不同的数。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
set<int> st;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
st.insert(x);
}
if (k == 1) {
cout << (st.size() == 1 ? 1 : -1) << "\n";
continue;
}
cout << 1 + max(0, (int(st.size()) - 2)) / (k - 1) << "\n";
}
return 0;
}

C. Discrete Acceleration

题意

有一条公路从坐标 $0$ 到坐标 $l$ 长为 $l$ 米,初始时甲车在坐标 $0$ 处,乙车在坐标 $l$ 处。

公路上有 $n$ 个加速点,两车初速度均为 $1m/s$,经过一个加速点增加 $1m/s$,计算两车多久相遇。

题解

计算两车到每个加速点的时间,两车会在甲更快到的加速点和乙更快到的加速点之间相遇。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(15);
int t;
cin >> t;
while (t--) {
int n, l;
cin >> n >> l;
vector<double> a(n + 2);
a[0] = 0;
a[n + 1] = l;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
vector<double> t1(n + 2), t2(n + 2);
t1[0] = 0;
t2[n + 1] = 0;
for (int i = 1; i < n + 2; i++) {
t1[i] = t1[i - 1] + (a[i] - a[i - 1]) / i;
}
for (int i = n; i >= 0; i--) {
t2[i] = t2[i + 1] + (a[i + 1] - a[i]) / (n + 1 - i);
}
double ans = 0.0;
for (int i = 1; i < n + 2; i++) {
if (t1[i - 1] <= t2[i - 1] and t1[i] >= t2[i]) {
ans = max(t1[i - 1], t2[i]) + (a[i] - a[i - 1] - abs(t1[i - 1] - t2[i]) * (t1[i - 1] < t2[i] ? i : n + 2 - i)) / (n + 2);
break;
}
}
cout << ans << "\n";
}
return 0;
}

D. Searchlights

题意

在二维平面上给出 $n$ 个人和 $m$ 个探照灯的坐标 $(a,b)$ 和 $(c,d)$,每次操作可以选择:

  • 将所有人横坐标加一
  • 将所有人纵坐标加一

问使得任一人都不在任一探照灯左下方的最少操作次数。

题解

对于第 $i$ 个人和第 $j$ 个探照灯 ,如果 $dx + a_i \ge c_j + 1$,那么他一定可以移出探照灯的范围,否则,对于所有小于 $dx = c_j - a_i + 1$ 的移动次数,它们对应的纵坐标移动次数至少要为 $d_j - b_i + 1$ 次才能移出该探照灯的范围。

对于每个人枚举 $m$ 个探照灯,记录并更新每个横坐标移动次数对应的纵坐标移动次数的最大值,最后从后向前遍历并更新纵坐标的最大移动次数,因为如果之前移动了更多的横坐标仍需将纵坐标移动这么多次,那么对于现在移动了更少的横坐标也是必须的。

$dp_i$ 的含义为横坐标移动次数为 $i$ 时,纵坐标的移动次数至少要为 $dp_i$ 才能保证所有人都移出探照灯的范围。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<int> a(n), b(n);
for (int i = 0; i < n; i++) {
cin >> a[i] >> b[i];
}
vector<int> c(m), d(m);
for (int i = 0; i < m; i++) {
cin >> c[i] >> d[i];
}
constexpr int N = 1e6 + 10;
vector<int> dp(N);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (a[i] <= c[j]) {
dp[c[j] - a[i]] = max(dp[c[j] - a[i]], d[j] + 1 - b[i]);
}
}
}
for (int i = N - 2; i >= 0; i--) {
dp[i] = max(dp[i], dp[i + 1]);
}
int ans = INT_MAX;
for (int i = 0; i < N; i++) {
ans = min(ans, i + dp[i]);
}
cout << ans << "\n";
return 0;
}

E. Avoid Rainbow Cycles

题意

给出 $m$ 个集合 $A$,所有元素大小在 $[1,n]$ 之间。

每个集合中的元素两两成边,颜色与集合相同,不同集合颜色不同。

给出大小为 $m,n$ 的两个数组 $a,b$,从 $A_i$ 中移除值为 $j$ 的元素花费为 $a_i + b_j$ 。

彩虹环指边颜色不重复的环,问使得图中无彩虹环的最少花费。

题解

构造集合和数值的二分图,$A_i$ 与值为 $j$ 的元素间边权为 $a_i + b_j$,最少花费即为总边权和减去二分图的最大生成树。

代码

#include <bits/stdc++.h>
using namespace std;
constexpr int N = 2e5 + 10; int fa[N]; int Find(int x) {
return fa[x] == x ? x : fa[x] = Find(fa[x]);
} void Union(int x, int y) {
x = Find(x);
y = Find(y);
if (x != y) {
if (x < y) fa[y] = x;
else fa[x] = y;
}
} void Init() {
for (int i = 0; i < N; i++) {
fa[i] = i;
}
} int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
Init();
int m, n;
cin >> m >> n;
vector<int> a(m);
for (auto &x : a) cin >> x;
vector<int> b(n);
for (auto &x : b) cin >> x;
long long sum = 0;
vector<tuple<int, int, int>> edges;
for (int i = 0; i < m; i++) {
int s;
cin >> s;
for (int j = 0; j < s; j++) {
int x;
cin >> x;
--x;
sum += a[i] + b[x];
edges.emplace_back(a[i] + b[x], i + n, x);
}
}
sort(edges.begin(), edges.end(), greater<>());
for (auto [w, u, v] : edges) {
if (Find(u) != Find(v)) {
Union(u, v);
sum -= w;
}
}
cout << sum << "\n";
return 0;
}

F. Two Different

题意

给出一个大小为 $n$ 的数组 $a$,其中 $a_i = i$ 。

每次操作可以选取两个元素并用二元映射函数 $f$ 赋值:$a_i = a_j = f(a_i,a_j)$ 。

试给出一种操作方式,使得无论映射函数如何,最终 $a$ 中最多只有两个不同的数。

题解

如果数组大小为 $2^p$,那么最终可以都变为一个数。

如:

  1. 1 2 3 4
  2. 5 5 6 6
  3. 7 7 7 7

如果数组大小不为 $2^p$,对两个端点所在的 $2^p$ 长区间各操作一次即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<pair<int, int>> ans;
function<void(int, int)> dfs = [&](int l, int r) {
if (l == r) return;
int mid = (l + r) / 2;
dfs(l, mid);
dfs(mid + 1, r);
for (int i = l, j = mid + 1; i <= mid; i++, j++) {
ans.emplace_back(i, j);
}
};
int p = 1 << __lg(n);
dfs(1, p);
if (p != n) {
dfs(n - p + 1, n);
}
cout << ans.size() << "\n";
for (auto [x, y] : ans) {
cout << x << ' ' << y << "\n";
}
return 0;
}

参考博客

https://blog.csdn.net/qq_45458915/article/details/108912813

Grakn Forces 2020的更多相关文章

  1. CF Grakn Forces 2020 1408E Avoid Rainbow Cycles(最小生成树)

    1408E Avoid Rainbow Cycles 概述 非常有趣的题目(指解法,不难,但很难想) 非常崇拜300iq,今天想做一套div1时看见了他出的这套题Grakn Forces 2020,就 ...

  2. Grakn Forces 2020 ABCDE题解

    看到老外评论区中说,这场的难度估计是\(div.1\)和\(div.1.5\)的合并 A. Circle Coloring #构造 题目链接 题意 给定三个长度为\(n\)数组\(a,b,c\),要你 ...

  3. hdu 2020

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2020 思路:优先队列水过priority_queue #include <cstdio> ...

  4. Problem 2020 组合(FOJ)

    Problem 2020 组合 Accept: 714    Submit: 1724Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem ...

  5. Codeforces Round #334 (Div. 2) A. Uncowed Forces 水题

    A. Uncowed Forces Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/604/pro ...

  6. Hackerrank 2020 February 2014 解题报告

    Hackerrank 2020 February 2014 解题报告 比赛链接 Sherlock and Watson (20分) 题意:给定一个数组,向右平移K次,然后有Q个询问,问第x位置上是几 ...

  7. 2020: [Usaco2010 Jan]Buying Feed, II

    2020: [Usaco2010 Jan]Buying Feed, II Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 220  Solved: 162[ ...

  8. 2019年IntelliJ IDEA 最新注册码,亲测可用(截止到2020年3月11日)

    2019年IntelliJ IDEA 最新注册码(截止到2020年3月11日) 操作步骤: 第一步:  修改 hosts 文件 ~~~ 在hosts文件中,添加以下映射关系: 0.0.0.0 acco ...

  9. loj#2020 「AHOI / HNOI2017」礼物 ntt

    loj#2020 「AHOI / HNOI2017」礼物 链接 bzoj没\(letex\),差评 loj luogu 思路 最小化\(\sum\limits_1^n(a_i-b_i)^2\) 设改变 ...

随机推荐

  1. Lesson_strange_words2

    cap 大写字母 mechanical 机械的,力学的 optical 光学的,视觉的 charge 电荷,负载 couple 耦合的,联接的,成对的 charge-coupled device 电荷 ...

  2. 【剑指 Offer】03.1.不修改数组找出重复的数字

    找出数组中重复的数字. 在一个长度为 n + 1 的数组 nums 里的所有数字都在 1-n 的范围内.所以数组中至少有一个是重复的.请找出数组中任意一个重复的数字. 示例 1: 输入: [2, 3, ...

  3. 【C++】《Effective C++》第一章

    第一章 让自己习惯C++ C++是一个威力强大的语言,带着众多特性,但是在你可以驾驭其威力并有效运用其特性之前,你必须先习惯C++的办事方式. 条款01:视C++为一个语言联邦 如今的C++已经是个多 ...

  4. 天梯赛练习 L3-016 二叉搜索树的结构 (30分)

    题目分析: 用数型结构先建树,一边输入一边建立,根节点的下标为1,所以左孩子为root*2,右孩子为root*2+1,输入的时候可用cin输入字符串也可用scanf不会超时,判断是否在同一层可以判断两 ...

  5. 【EXP】根据字段导出数据query

    exp有些时候需要根据字段来进行导出操作 例如:想要导出hr用户中的employees中salary要大于4000的数据 这样的话需要添加where语句,需要用到的参数是query 查看下大于4000 ...

  6. 企业项目迁移go-zero全攻略(二)

    承接上篇:上篇文章讲到 go-zero 架构设计和项目设计.本篇文章接着这个项目设计,将生成的 app 模块 中 gateway 和 RPC 进行改造.废话不多说,让我们开始! gateway ser ...

  7. 【中文】【deplearning.ai】【吴恩达课后作业目录】

    [目录][吴恩达课后作业目录] 吴恩达深度学习相关资源下载地址(蓝奏云) 课程 周数 名称 类型 语言 地址 课程1 - 神经网络和深度学习 第1周 深度学习简介 测验 中英 传送门 无编程作业 编程 ...

  8. uni-app开发经验分享十: 封装request请求

    http.js //封装requset,uploadFile和downloadFile请求,新增get和post请求方法 let http = { 'setBaseUrl': (url) => ...

  9. Redis 实战 —— 06. 持久化选项

    持久化选项简介 P61 Redis 提供了两种不同的持久化方法来将数据存储到硬盘里面. RDB(redis database):可以将某一时刻的所有数据都写入硬盘里面.(保存的是数据本身) AOF(a ...

  10. Ansible自动化运维工具的使用

                                 Ansible自动化运维工具的使用       host lnventory 管理主机 ip  root账号密码 ssh端口 core mod ...