D. Same Count One(Polynomial Round 2022 (Div. 1 + Div. 2, Rated, Prizes!))

题意

给定 \(n\) 个长度为 \(m\) 的 01 序列,每次操作可以选择两个序列a1, a2,并选择一个\(pos\), std::swap(a1[pos], a2[pos]), 求是每个序列中的 \(1\) 的个数都相等所需的最小操作数。

思路

可以发现 (\(1\) 的总数 ) \(\bmod \ n \neq 0\) 时, 是无解的。

令 \(avg =\) (\(1\) 的总数 ) \(/ n\), 我们可以把这 \(n\) 个序列分为两类,严格小于 \(avg\) 的 和严格大于 \(avg\) 的,其他的序列可以丢掉。

严格大于 \(avg\) 的序列都可以为 严格小于 \(avg\) 的序列补充 \(1\), 直到 严格大于 \(avg\) 的序列 \(1\) 的个数等于 \(avg\) 或者 严格小于 \(avg\) 的序列 \(1\) 个数等于 \(avg\)。

直接模拟即可。

实现

void solve_problem() {
int n, m;
std::cin >> n >> m;
std::vector a(n, std::vector<int>(m, 0));
int avg = 0;
for (int i = 0;i < n; i++) {
for (int j = 0; j < m; j++) {
std::cin >> a[i][j];
avg += a[i][j];
}
}
if (avg % n == 0) {
if (n == 1) {
std::cout << 0 << "\n";
return;
}
avg /= n;
std::vector<std::pair<int,int>> q1, q2;
for (int i = 0; i < n; i++) {
int cnt = 0;
for (int j = 0; j < m; j++) {
cnt += a[i][j];
}
if(cnt < avg) q1.push_back({cnt, i});
else if (cnt > avg) q2.push_back({cnt, i});
}
int ans1 = 0;
std::vector<std::array<int, 3>> ans2;
for (int i = 1; i <= n; i++) {
if (q1.empty() || q2.empty()) break;
auto [c1, i1] = q1[0];
auto [c2, i2] = q2[0];
int d = avg - c1;
for (int j = 0; j < m; j++) {
if (d == 0 || c2 == avg) {
break;
}
if (a[i2][j] == 1 && a[i1][j] == 0) {
std::swap(a[i2][j], a[i1][j]);
c1++;
c2--;
d--;
ans2.push_back({i2 + 1, i1 + 1, j + 1});
ans1++;
}
}
q1[0] = {c1, i1};
q2[0] = {c2, i2};
if (c1 == avg) q1.erase(q1.begin());
if (c2 == avg) q2.erase(q2.begin());
}
std::cout << ans1 << "\n";
for (auto [x, y, z] : ans2) {
std::cout << std::max(x, y) << " " << std::min(y, x) << " " << z << "\n";
}
} else {
std::cout << -1 << "\n";
}
}

D. Watch the Videos(2022-2023 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror, ICPC Rules, Preferably Teams))

题意

有 \(n\) 个大小随意的视频和 \(1\) 个大小为 \(m\) 的磁盘,视频要下载到磁盘中才可以开始观看,下载第 \(i\) 个视频花费 \(a_i\) 的时间,开始下载第\(i\)个视频时,磁盘中要至少有\(a_i\)的空间才可以开始,下载完成需要花费 \(1\) 的时间观看完,看完之后视频立刻被从磁盘中删除,求看完所有视频需要的时间。(一次只能下载一个视频,观看视频的时候可以开始下载视频)

思路

最坏的答案(每次看完一个视频后才开始下载下一个视频), 计算方法为:

\[ans = n + \sum_{i = 1}^n a_i
\]

可以发现如果在观看视频时下载视频,答案就可以 \(-1\) 。

要想使答案最小,只需要尽可能多的在观看视频时开始下载视频即可。

假设视频序列 \(a\) 从小到大排序, 那么可以找到一个最大的 \(pos (1\leq pos \leq n)\), 使得序列

\[[a_{pos},a_1,a_{pos-1},a_2,a_{pos-2},a_3,\cdots]
\]

相邻两个数的和小于等于 \(m\)。

按照这个序列观看,有 \(pos - 1\) 个视频是在正在观看视频时开始下载的。可以使答案减少 \(pos - 1\)。

\(pos\) 是满足单调性的,因此可以二分来找到最大的 \(pos\)。

实现

void solve_problem() {
int n, m;
std::cin >> n >> m;
std::vector<int> a(n);
for (auto &x : a) {
std::cin >> x;
}
std::sort(a.begin(), a.end());
auto check = [&](int x) {
int l = 0, r = x - 1;
while (l < r) {
if (a[r] > m - a[l]) return false;
r--;
l++;
}
return true;
};
int l = 1, r = n, ans = 0;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
std::cout << std::accumulate(a.begin(), a.end(), 0LL) + (n - ans + 1) << "\n";
}

D. Range = √Sum(Codeforces Round #836 (Div. 2))

题意

构造一个长度为 \(n\) 的数组 \(a_1,a_2, a_3, \dots,a_n\),使 \(a_i\) 各不相同,且 \(max(a_1,a_2, a_3, \dots,a_n) - min(a_1,a_2, a_3, \dots,a_n) = \sqrt{a_1,a_2, a_3, \dots,a_n}\) 。

思路

当 \(n\) 为偶数时, 数组为:

\[\frac{n}{2},\frac{n}{2} + 1,\cdots ,n,n + 1,n + 2,n + \frac{n}{2}.
\]

数组可以被分成 \(\frac{n}{2}\) 组,每组的和都为 \(2n\)。

当 \(n\) 为奇数时,我们尝试 \(max(a) - max(b) = n + 1\), 因此数组的和应为 \(n^2 + 2n + 1\)。

尝试使用 \(n - 1\) 个数分为 \(\frac{n-1}{2}\) 组,每组和为 \(2(n+1)\), 组成的数组和为 \(n^2 - 1\)。

此时这 \(n - 1\) 个数为:

\[\frac{n - 1}{2} + 2,\frac{n - 1}{2} + 3,\cdots,\frac{n - 1}{2} + \frac{n - 1}{2},n + 2,n + 3,\cdots,n + \frac{n - 1}{2} + 1
\]

知道了最小项,最大项也可以计算出来 \(n + \frac{n - 1}{2} + 3\)。

这时数组的和为:

\[n^2 - 1 + n + \frac{n - 1}{2} + 3 = n^2 + n + \frac{n - 1}{2} + 2
\]

距离 \(n^2 + 2n + 1\) 还需要:

\[\begin{aligned}
(n^2 + 2n + 1) - (n^2 + n + \frac{n - 1}{2} + 2) &= n - \frac{n - 1}{2} - 1\\
&=\frac{2n - n + 1 - 2}{2}\\
&=\frac{n - 1}{2}
\end{aligned}
\]

我们可以让 第 \(\frac{n - 1}{2} + 1\) 项到第 \(n - 1\) 项都 \(+1\) 来抵消掉 \(\frac{n - 1}{2}\)。

因为第 \(n - 1\) 项 \(n + \frac{n - 1}{2} + 1\) 与 第 \(n\) 项 \(n + \frac{n - 1}{2} + 3\) 相差 \(2\),所以 \(+1\) 操作不会使数组产生重复的数。

此时我们的数组已经构造完成:

\[\frac{n - 1}{2} + 2,\frac{n - 1}{2} + 3,\cdots,\frac{n - 1}{2} + \frac{n - 1}{2},n + 3,n + 4,\cdots,n + \frac{n - 1}{2} + 2,n + \frac{n - 1}{2} + 3
\]

实现

void solve_problem() {
int n;
std::cin >> n;
if (n % 2 == 0) {
for (int i = 0; i < n/2; i++) std::cout << (n/2 + i) << " ";
for (int i = 1; i <= n/2; i++) std::cout << (n + i) << " ";
std::cout << "\n";
} else {
for (int i = 1; i <= (n - 1) / 2; i++) std::cout << (n - 1) / 2 + i + 1 << " ";
for (int i = 1; i <= (n - 1) / 2; i++) std::cout << n + i + 2 << " ";
std::cout << n + (n - 1) / 2 + 3<< "\n";
}
}

CF构造题1600-1800(1)的更多相关文章

  1. CF1110E Magic Stones(构造题)

    这场CF怎么这么多构造题…… 题目链接:CF原网 洛谷 题目大意:给定两个长度为 $n$ 的序列 $c$ 和 $t$.每次我们可以对 $c_i(2\le i<n)$ 进行一次操作,也就是把 $c ...

  2. cf251.2.C (构造题的技巧)

    C. Devu and Partitioning of the Array time limit per test 1 second memory limit per test 256 megabyt ...

  3. hdu4671 Backup Plan ——构造题

    link:http://acm.hdu.edu.cn/showproblem.php?pid=4671 其实是不难的那种构造题,先排第一列,第二列从后往前选. #include <iostrea ...

  4. Educational Codeforces Round 7 D. Optimal Number Permutation 构造题

    D. Optimal Number Permutation 题目连接: http://www.codeforces.com/contest/622/problem/D Description You ...

  5. Codeforces 482 - Diverse Permutation 构造题

    这是一道蛮基础的构造题. - k         +(k - 1)      -(k - 2) 1 + k ,    1 ,         k ,             2,    ....... ...

  6. BZOJ 3097: Hash Killer I【构造题,思维题】

    3097: Hash Killer I Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 963  Solved: 36 ...

  7. 做了一道cf水题

    被一道cf水题卡了半天的时间,主要原因时自己不熟悉c++stl库的函数,本来一个可以用库解决的问题,我用c语言模拟了那个函数半天,结果还超时了. 题意大概就是,给定n个数,查询k次,每次查询过后,输出 ...

  8. CDOJ 1288 旅游的Final柱 构造题

    旅游的Final柱 题目连接: http://acm.uestc.edu.cn/#/problem/show/1288 Description 柱神要去打Final啦~(≧▽≦)/~啦啦啦 柱神来到了 ...

  9. CodeForces 297C Splitting the Uniqueness (脑补构造题)

    题意 Split a unique array into two almost unique arrays. unique arrays指数组各个数均不相同,almost unique arrays指 ...

  10. HDU 5355 Cake (WA后AC代码,具体解析,构造题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5355 题面: Cake Time Limit: 2000/1000 MS (Java/Others) ...

随机推荐

  1. Vue学习之--------Vue中自定义插件(2022/8/1)

    文章目录 1.插件的基本介绍 2.实际应用 2.1 目录结构 2.2 代码实例 2.2.1 学校组件(School.vue) 2.2.2 学生组件(Student.vue) 2.2.3 定义的插件 2 ...

  2. SQL--插入单引号值

    sql语句中插入单引号的值需要多写一个单引号进行转义 例如:插入一个值为student' name的值 update table set name='student'' name'

  3. 如何解读Linux Kernel OOPS信息

    OOPS信息解读 root@firefly:~/mnt/module# insmod oops_module.ko [ 867.140514] Unable to handle kernel NULL ...

  4. 通过jmeter,将数据库数据查询出来并打印

    1. 连接数据库 1.1 添加jdbc驱动路径 1.2 JDBC Connection Configuration    1.3 JDBC Request 2. 查询数据库数据并打印 2.1 定义变量 ...

  5. ubuntu 22.04安装多个gcc

    sudo apt install gcc-9 g++-9 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 - ...

  6. js 获取相同name元素的属性值

    如图有8-12月5个文本域,id为plan8-12,name同为plan. 现在要获取name同为plan的所有属性值: 方法一: var allplan =document.getElementsB ...

  7. Linux 基础-新手必备命令

    Linux 基础-新手必备命令 概述 常见执行 Linux 命令的格式是这样的: 命令名称 [命令参数] [命令对象] 注意,命令名称.命令参数.命令对象之间请用空格键分隔. 命令对象一般是指要处理的 ...

  8. Spring03:案例转账功能(事务问题)、动态代理解决、AOP

    今日内容--核心2AOP 完善Account案例 分析案例中的问题 回顾之前讲过的技术--动态代理 动态代理的另一种实现方式 解决案例中的问题 AOP的概念 Spring中的AOP相关术语 Sprin ...

  9. 【JUC】信号量Semaphore详解

    欢迎关注专栏[JAVA并发] 欢迎关注个人公众号-- JAVA旭阳 前言 大家应该都用过synchronized 关键字加锁,用来保证某个时刻只允许一个线程运行.那么如果控制某个时刻允许指定数量的线程 ...

  10. Doris安装部署

    下载安装 Doris运行在Linux环境中,推荐 CentOS 7.x 或者 Ubuntu 16.04 以上版本,同时你需要安装 Java 运行环境(JDK最低版本要求是8) 1.下载安装包 下载地址 ...