Codeforces Round #792 (Div. 1 + Div. 2) A-E
Codeforces Round #792 (Div. 1 + Div. 2) A-E
A
题目
https://codeforces.com/contest/1684/problem/A
题解
思路
知识点:数学。
显然长度大于等于3的数字串的最小数位是完全可以通过这些操作留到最后。
长度等于2的数字串只可能是个位数字。
时间复杂度 \(O(n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
string str;
cin >> str;
if (str.length() == 2) cout << str.back() << '\n';
else {
int ans = ~(1 << 31);
for (int i = 0;i < str.length();i++) ans = min(ans, str[i] - '0');
cout << ans << '\n';
}
}
return 0;
}
B
题目
https://codeforces.com/problemset/problem/1684/B
题解
思路
知识点:数学,构造。
容易得到三个式子
y &= mz + b\\
z &= nx + c\\
\]
其中 \(k,m,n \in \mathbb{N^+}\)。
通过代入得到
\]
由于 \(z \mod x = c\) ,因此有 \(x > c\) ,考虑 \(k = 1,m = 1,n = 0\) 得到 \(x = a+b+c , y = b+c , z = c\) 。
时间复杂度 \(O(1)\)
空间复杂度 \(O(1)\)
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
long long a, b, c;
cin >> a >> b >> c;
cout << a + b + c << ' ' << b + c << ' ' << c << '\n';
}
return 0;
}
C
题目
https://codeforces.com/problemset/problem/1684/C
题解
思路
知识点:模拟,排序。
通过排序完数组和原来的对比数组,找到第一组两个在同一行需要交换位置的点,如果超过2个同一行的需要交换的点说明一次交换不可行直接输出-1,如果为0个则不需要交换,设置任意一个点作为两个交换的点(即不交换)。
在确认两个交换点之后,对原数组每行进行交换,每行交换之后判断是否是排序好的,如果有一行不是说明不可行输出-1,否则为答案。
时间复杂度 \(O(nm \log m)\)
空间复杂度 \(O(nm)\)
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
bool solve() {
int n, m;
cin >> n >> m;
vector<vector<int>> a(n, vector<int>(m)), b(n, vector<int>(m));
for (int i = 0;i < n;i++) {
for (int j = 0;j < m;j++) {
cin >> a[i][j], b[i][j] = a[i][j];
}
}
for (int i = 0;i < n;i++) {
sort(b[i].begin(), b[i].end());
}
int pos1 = -1, pos2 = -1;
for (int i = 0;i < n;i++) {
for (int j = 0;j < m;j++) {
if (a[i][j] != b[i][j]) {
if (!~pos1) pos1 = j;
else if (!~pos2) pos2 = j;
else return false;
}
}
if (~pos1) break;
}
if (!~pos1) pos2 = pos1 = 0;
for (int i = 0;i < n;i++) {
swap(a[i][pos1], a[i][pos2]);
if (!is_sorted(a[i].begin(), a[i].end())) return false;
}
cout << pos1 + 1 << ' ' << pos2 + 1 << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
D
题目
https://codeforces.com/contest/1684/problem/D
题解
思路
知识点:贪心(贪给我使劲贪)。
结论:跳过以 \(n-1-i-a[i]\) 排序的前 \(k\) 小值的点,或者说是 \(i+a[i]\) 排序的前 \(k\) 大值的点。
意识流证明:
\(n-1-i-a[i]\) 可以理解为跳过一个点后的代价改变量(\(i+a[i]\) ,即 \(a[i]-(n-1-i)\) 可以理解为跳过一个点的代价减少量),而只要选改变量最小的 \(k\) 个点,并且减去在每个跳过的点因为之前跳过点产生的额外代价(跳过的点不应该有代价)共 \(k(k-1)/2\) ,可以得到一个最小实际改变量(实际上一定存在一种方法使其小于 \(0\) ,这也说明了最优方法一定把 \(k\) 次跳过机会用完),加上改变量就能使总代价最小。
数学证明:微扰法。
假设方案不是跳过最小改变量的 \(k\) 个位置,则存在更优方案。
首先,存在某个位置 \(i\) 没有被跳过,某个位置 \(j\) 被跳过,且有 \(n-1-i-a[i]<n-1-j-a[j]\),即 \(i+a[i]>j+a[j]\) ,有两种情况\(i<j\) 和 \(i>j\) 。
当 \(i<j\) 时,从 \(a[j]\) 到 \(a[i]\) 会让 \(j-i\) 个位置代价加一,并且答案减去 \(a[i]\) 加上 \(a[j]\),又因为 \(i+a[i]>j+a[j]\) , 可以得到改变量 \(a[j] - a[i] + j - i < 0\) ,改变一定更优。\(i>j\) 的情况同理。
时间复杂度 \(O(n\log n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[200007];
bool solve() {
int n, k;
cin >> n >> k;
///显然k个跳点都选上是最小的必要条件
ll ans = -1LL * k * (k - 1) / 2;///每个跳过的点都要减掉之前跳过点产生的额外代价,因为跳过的点没有代价
for (int i = 0;i < n;i++) cin >> a[i], ans += a[i], a[i] = n - 1 - i - a[i];///n-i-a[i]代表跳过这个点相对于不跳过会产生多少代价
sort(a, a + n);///用于挑选前k个产生代价最小的点跳过
for (int i = 0;i < k;i++) ans += a[i];///跳过产生的代价变化
cout << ans << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
E
题目
https://codeforces.com/contest/1684/problem/E
题解
思路
知识点:数据结构,贪心。
MEX:序列中最小未出现的自然数(包括0)。
例如,\(MEX(\{ 0,1,2,4,5 \})=3\) , \(MEX(\{ 1,2,4,5 \}) = 0\) 。
观察\(DIFF - MEX\) 的结果,发现 \(MEX\) 数之前的数必然都出现,则种类数一定和 \(MEX\) 一样,因此结果就是大于 \(MEX\) 的数的种类数。
我们发现,当通过修改数字使得 \(MEX\) 增大时,\(DIFF\) 必然是不增的,因此可以先考虑在 \(k\) 次操作得到尽可能大的 \(MEX\) ,而数组长度为 \(n\) ,则必然可以通过修改使在 \(n\) 以内的所有 \(MEX\) 都能得到,所以可以从 \(0\) 开始遍历 ,若存在该数字则继续,否则通过一次操作得到这个数字,这样就可以得到 \(k\) 次操作后最大可能的 \(MEX\) 了,这样操作得到的 \(MEX\) 可能会大于 \(n\) 但不需要限制操作次数使其合法,因为大于等于 \(n\) 在之后处理中也都能得到正确结果 \(0\) 。
得到最大的 \(MEX\) 后,只要考虑操作比 \(MEX\) 大的就行(即使可能用不完 \(k\) 次),首先因为大于 \(MEX\) 的数字种类即是答案,所以优先取完其尽可能多的种类能直接降低答案,其次 \(MEX\) 是操作 \(k\) 次内的必然结果,无论如何都能在 \(k\) 次内达到,而大于 \(MEX\) 的数字种类即是答案,那么只考虑 \(k\) 次操作后(可能不到 \(k\) 次就取完了,剩下的操作可以理解为用小于 \(MEX\) 的数补全,从而也能达到 \(MEX\) ,但不改变答案 \(0\))这些数的种类即可。特别地,最大 \(MEX\) 在取的时候可能大于等于其最大可能值 \(n\) ,即最后大于 \(MEX\) 数的种类必然为\(0\) ,也即 \(k\) 次操作内必然取完大于 \(MEX\) 的数,答案也为 \(0\) ,所以在之前的操作不需要通过限制操作次数来限制 \(MEX\) 。
时间复杂度 \(O(n \log^2 n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
bool solve() {
int n, k;
cin >> n >> k;
map<int, int> m;///用于元素与数量映射
for (int i = 0;i < n;i++) {
int tmp;
cin >> tmp;
m[tmp]++;
}
int mex = 0;
for (int i = 0, kk = k;;i++) {
if (!m.count(i)) {
if (kk) kk--;
else {
mex = i;
break;
}
}
}
priority_queue<int, vector<int>, greater<int>> pq;
for (auto i : m) if (i.first > mex) pq.push(i.second);
while (!pq.empty() && k >= pq.top()) { ///答案等于大于mex的元素种类,所以k<最小个数元素时,不用继续,此种类补全k次后不会消失,留着就行
k -= pq.top();
pq.pop();
}
cout << pq.size() << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
Codeforces Round #792 (Div. 1 + Div. 2) A-E的更多相关文章
- Codeforces Round #792 (Div. 1 + Div. 2) // C ~ E
比赛链接:Dashboard - Codeforces Round #792 (Div. 1 + Div. 2) - Codeforces C. Column Swapping 题意: 给定一个n*m ...
- Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship
Problem Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...
- Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)
Problem Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...
- Educational Codeforces Round 43 (Rated for Div. 2)
Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...
- Educational Codeforces Round 35 (Rated for Div. 2)
Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...
- Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...
- Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...
- Educational Codeforces Round 63 (Rated for Div. 2) 题解
Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...
- Educational Codeforces Round 39 (Rated for Div. 2) G
Educational Codeforces Round 39 (Rated for Div. 2) G 题意: 给一个序列\(a_i(1 <= a_i <= 10^{9}),2 < ...
随机推荐
- xss攻击和防御
简介 XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允 ...
- 应用程序application和库工程library之间的切换
知识点: Application作为应用程序启动:apply plugin: 'com.android.application' Library作为库工程被引用: apply plugin: 'com ...
- C#/VB.NET 获取Excel中图片所在的行、列坐标位置
本文以C#和vb.net代码示例展示如何来获取Excel工作表中图片的坐标位置.这里的坐标位置是指图片左上角顶点所在的单元格行和列位置,横坐标即顶点所在的第几列.纵坐标即顶点所在的第几行.下面是获取图 ...
- 聊聊redis的主从复制吧
聊聊基础概念 主从复制与主从替换 主从复制不同于主从替换,主从复制是正常情况下主节点同步数据到从节点:主从替换是主节点挂了之后,把从节点替换为主节点: 从节点存在的意义:备份主节点数据+负载均衡(对外 ...
- 企业应用架构研究系列二十八:身份认证 Beginning Out With IdentityServer4
在.Netcore 技术栈中,一直在使用了开源组件IdentityService4进行身份管理,其功能的强大和易用性的确很受开发者喜欢,但是最近其开源组织Duende Software 开始对其进行商 ...
- Apollo的docker配置详解步骤
Apollo 的docker配置 基础环境 centOS7 + Docker服务 + mysql服务 1. 下载Apollo的包 git clone https://github.com/ctripc ...
- 网络协议OSI模型-TCP/IP-三次握手
OSI模型 在制定计算机网络标准方面,起着重大作用的两大国际组织是:国际电信联盟电信标准化部门,与国际 标准组织(ISO),虽然它们工作领域不同,但随着科学技术的发展,通信与信息处理之间的界限开始 变 ...
- C++基础-1-内存管理(全局区、堆区、栈区)
1. 内存管理 1.1 全局区 1 #include<iostream> 2 using namespace std; 3 4 // 全局变量 5 int g_a = 10; 6 int ...
- 配置Linux的时钟同步
公众号关注 「开源Linux」 回复「学习」,有我为您特别筛选的学习资料~ Ubuntu系统默认的时钟同步服务器是ntp.ubuntu.com,Debian则是0.debian.pool.ntp.or ...
- vue3中的四种插槽的介绍-保证让你看看的明明白白!
插槽 当组件中只有一个插槽的时候,我们可以不设置 slot 的 name 属性. v-slot 后可以不带参数,但是 v-slot 在没有设置 name 属性的时候, 插槽口会默认为"def ...