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 < ...
随机推荐
- 关于Jupyter Notebook无法自动补全(Autocompletion),报错TypeError: __init__() got an unexpected keyword argument 'column' 的解决方案
关于Jupyter Notebook无法自动补全(Autocompletion),报错TypeError: __init__() got an unexpected keyword argument ...
- Linux ubuntu下docker容器安装和基础命令
Docker介绍: 云计算就好比大货轮,docker就是集装箱虚拟机虽然可以隔离出很多"子电脑",但占用空间更大,启动更慢,虚拟机软件可能还要花钱(例如VMWare). 而容器技术 ...
- jmeter工具初探
jmeter工具初探 一.jmeter工具介绍 1.一种免费的java开源工具,可以进行二次开发 2.运行环境:java运行环境,需要安装JDK,配置JAVAHOME 环境变量 3.下载jmeter: ...
- XCTF练习题---MISC---坚持60S
XCTF练习题---MISC---坚持60S flag:flag{DajiDali_JinwanChiji} 解题步骤: 1.观察题目,下载附件,是一个java文件 2.打开玩了一会,真鸡儿难,试着反 ...
- [AcWing 862] 三元组排序
点击查看代码 #include <iostream> #include <algorithm> using namespace std; const int N = 1e5 + ...
- [AcWing 28] 在O(1)时间删除链表结点
点击查看代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * L ...
- 一文搞懂CDN加速原理
开源Linux 长按二维码加关注~ 一.什么是 CDN CDN的全称是(Content Delivery Network),即内容分发网络.其目的是通过在现有的Internet中增加一层新的CACHE ...
- vue - Vue脚手架(终结篇)/ vue动画
几天的内容不是很多,因为我们脚手架的学习告一段落了,也是为了跟明天开始的内容有一个区分. 明天将会有一个非常重要的内容来了,各位,vue中的ajax他来了,这个绝对是重量级,有点兴奋! 十一.TODO ...
- Linux的快捷使用(不断更新中)
Linux 命令行提示符 ~代表当前目录,即家目录,#是超级用户提示符,如果是普通用户使用$ 基本快捷键的使用 移动光标命令 Ctrl+A:移动光标到开头 Ctrl+E:移动光标到结尾 Ctrl+F: ...
- linux下虚拟环境venv的创建与使用以及virtualenvwrapper
1.linux安装学习python虚拟环境 linux提供的虚拟环境工具 有virtualenv pipenv 2.我们需求是在linux上可以运行 一个django2 运行一个django1 3.安 ...