Codeforces Round #667 (Div. 3)
比赛链接:https://codeforces.com/contest/1409
A. Yet Another Two Integers Problem
题意
给出两个数 $a$ 和 $b$,有以下两种操作:
- $a+=k$
 - $a-=k$
 - $k \in [1, 10]$
 
问将 $a$ 变为 $b$ 最少需要操作多少次。
题解
$a,b$ 之差的绝对值对 $10$ 取上整。
代码
#include <bits/stdc++.h>
using namespace std; void solve() {
int a, b;
cin >> a >> b;
cout << (abs(b - a) + 9) / 10 << "\n";
} int main() {
int t;
cin >> t;
while (t--) solve();
}
B. Minimum Product
题意
给出两个数 $a$ 和 $b$,每次可以选择一个数减一,该操作最多执行 $k$ 次,同时要求 $a$ 不能小于 $x$,$b$ 不能小于 $y$,问 $a \cdot b$ 的最小值。
题解
如果给一个数减一,最佳方案就是一直给它减一,减到底后再减另一个数。
然后枚举先减 $a$ 还是先减 $b$ 即可。
代码一
#include <bits/stdc++.h>
using namespace std; void solve() {
int a, b, x, y, n;
cin >> a >> b >> x >> y >> n;
auto cal = [](int a, int b, int x, int y, int n) {
int mi = min(n, a - x);
n -= mi;
a -= mi;
mi = min(n, b - y);
n -= mi;
b -= mi;
return 1ll * a * b;
};
cout << min(cal(a, b, x, y, n), cal(b, a, y, x, n)) << "\n";
} int main() {
int t;
cin >> t;
while (t--) solve();
}
代码二
#include <bits/stdc++.h>
using namespace std; void solve() {
int a, b, x, y, n;
cin >> a >> b >> x >> y >> n;
auto cal = [&](int a, int b, int x, int y) {
int da = min(n, a - x);
int db = min(n - da, b - y);
return 1ll * (a - da) * (b - db);
};
cout << min(cal(a, b, x, y), cal(b, a, y, x)) << "\n";
} int main() {
int t;
cin >> t;
while (t--) solve();
}
C. Yet Another Array Restoration
题意
给出一个数组的大小 $n$ 和其中的两个元素 $x,y(x<y)$,试还原这个数组,要求:
- 数组中有 $n$ 个不同的正整数
 - 数组排序后相邻元素之差相等
 - 数组中的最大值尽可能地小
 
题解
数组相邻元素之差一定是 $y-x$ 的因子,据此分为以下三种情况:
- 因子过小,$x$ 到 $y$ 间可以容纳的元素个数大于 $n-2$,继续寻找更大的因子
 - 因子适中,$x$ 到 $y$ 间可以容纳的元素个数等于 $n-2$,此时以 $x$ 为起点,因子大小为步长输出 $n$ 次即可
 - 因子过大,$x$ 到 $y$ 间可以容纳的元素个数小于 $n-2$,因为最大值要尽量小,所以应尽可能地向 $x$ 的左端拓展正起点
 
代码
#include <bits/stdc++.h>
using namespace std; void solve() {
int n, x, y;
cin >> n >> x >> y;
int len = y - x;
for (int p = 1; p <= len; p++) {
if (len % p == 0) {
int can_hold = len / p - 1;
if (can_hold > n - 2) {
continue;
} else if (can_hold == n - 2) {
for (int i = x; i <= y; i += p)
cout << i << " \n"[i == y];
return;
} else {
int extra = n - 2 - can_hold;
int cnt = 0;
for (int i = x - p * min(extra, x / p - (x % p == 0)); cnt < n; i += p)
cout << i << " \n"[++cnt == n];
return;
}
}
}
} int main() {
int t;
cin >> t;
while (t--) solve();
}
D. Decrease the Sum of Digits
题意
给出一个数 $n$,每次可以给 $n$ 加上 $1$,找出使得 $n$ 的数位之和 $\le s$ 的最少操作数。
题解
给一个数位操作最终一定会使该数位的值变为 $0$(否则会一直增加数位之和),从低位到高位模拟即可。
代码
#include <bits/stdc++.h>
using namespace std; int sum(string s) {
int res = 0;
for (char c : s) res += c - '0';
return res;
} void solve() {
string n;
int s;
cin >> n >> s;
long long ans = 0, p = 1;
n = "0" + n;
for (int i = n.size() - 1; sum(n) > s; i--) {
ans += ('9' + 1 - n[i]) * p;
n[i] = '0';
++n[i - 1];
p *= 10;
}
cout << ans << "\n";
} int main() {
int t;
cin >> t;
while (t--) solve();
}
E. Two Platforms
题意
给出一个平面 $n$ 个点的坐标,有两个长为 $k$ 的平台,每个平台可以选择一个位置固定放置,问当所有点同时开始下落后,两个平台加起来最多可以接到多少个点。
题解
因为平台的纵坐标可以无限低所以只考虑横坐标即可。
将点的横坐标排序并计算两个 $dp$ 数组:
- $dp1$ 以该点为起点放置平台可以接到多少个点
 - $dp2$ 以该点或之后的点为起点放置平台最多可以接到多少个点
 
枚举第一个平台的起点 $i$,然后找到第一个坐标大于 $x+k$ 的点 $j$,答案即 $max(dp1[i] + dp2[j])$ 。
代码一
二分查找点 $j$
#include <bits/stdc++.h>
using namespace std; void solve() {
int n, k;
cin >> n >> k;
vector<int> x(n), y(n);
for (int i = 0; i < n; i++)
cin >> x[i];
for (int i = 0; i < n; i++)
cin >> y[i];
sort(x.begin(), x.end());
vector<int> dp1(n);
for (int i = 0; i < n; i++) {
int j = upper_bound(x.begin(), x.end(), x[i] + k) - x.begin();
dp1[i] = j - i;
}
vector<int> dp2(dp1);
for (int i = n - 2; i >= 0; i--)
dp2[i] = max(dp2[i], dp2[i + 1]);
int ans = 0;
for (int i = 0; i < n; i++) {
int j = upper_bound(x.begin(), x.end(), x[i] + k) - x.begin();
ans = max(ans, dp1[i] + (j < n ? dp2[j] : 0));
}
cout << ans << "\n";
} int main() {
int t;
cin >> t;
while (t--) solve();
}
代码二
双指针查找点 $j$
#include <bits/stdc++.h>
using namespace std; void solve() {
int n, k;
cin >> n >> k;
vector<int> x(n), y(n);
for (int i = 0; i < n; i++)
cin >> x[i];
for (int i = 0; i < n; i++)
cin >> y[i];
sort(x.begin(), x.end());
vector<int> dp1(n);
for (int i = 0, j = 0; i < n; i++) {
while (j < n and x[j] <= x[i] + k)
++j;
dp1[i] = j - i;
}
vector<int> dp2(dp1);
for (int i = n - 2; i >= 0; i--)
dp2[i] = max(dp2[i], dp2[i + 1]);
int ans = 0;
for (int i = 0, j = 0; i < n; i++) {
while (j < n and x[j] <= x[i] + k)
++j;
ans = max(ans, dp1[i] + (j < n ? dp2[j] : 0));
}
cout << ans << "\n";
} int main() {
int t;
cin >> t;
while (t--) solve();
}
F. Subsequences of Length Two
题意
给出两个小写字母串 $s$ 和 $t$,$t$ 长为 $2$。每次可以替换 $s$ 中的一个字母,该操作最多执行 $k$ 次,问 $t$ 作为 $s$ 的子序列最多可以出现多少次。
题解
$dp[i][j][k]$ 为前 $i$ 位操作 $j$ 次后有 $k$ 个 $t_0$ 时的子序列个数。
代码
#include <bits/stdc++.h>
using namespace std;
constexpr int INF = 1e9; void chmax(int &x, int y) {
x = max(x, y);
} int main() {
int n, k;
cin >> n >> k;
string s, t;
cin >> s >> t;
vector<vector<vector<int>>> dp(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, -INF)));
dp[0][0][0] = 0;
for (int i = 0; i < n; i++) {
for (int ck = 0; ck <= k; ck++) {
for (int cnt0 = 0; cnt0 <= n; cnt0++) {
if (dp[i][ck][cnt0] == -INF) continue;
int e0 = s[i] == t[0];
int e1 = s[i] == t[1];
int e01 = t[0] == t[1];
//不操作
chmax(dp[i + 1][ck][cnt0 + e0], dp[i][ck][cnt0] + (e1 ? cnt0 : 0));
if (ck < k) {
//s[i]变为t[0]
chmax(dp[i + 1][ck + 1][cnt0 + 1], dp[i][ck][cnt0] + (e01 ? cnt0 : 0));
//s[i]变为t[1]
chmax(dp[i + 1][ck + 1][cnt0 + e01], dp[i][ck][cnt0] + cnt0);
}
}
}
}
cout << *max_element(dp[n][k].begin(), dp[n][k].end()) << "\n";
}
Codeforces Round #667 (Div. 3)的更多相关文章
- Codeforces Round #667 (Div. 3) B、C、D、E 题解
		
抱歉B.C题咕了这么久 B. Minimum Product #枚举 #贪心 题目链接 题意 给定四个整数\(a, b, x, y\),其中\(a\geq x, b\geq y\),你可以执行不超过\ ...
 - Codeforces Round #667 (Div. 3)  E. Two Platforms  (双指针)
		
题意:有\(n\)个点往下落,你可以在最下面放两个长度为\(k\)的板子,问做多能接到多少个点. 题解:这题给纵坐标\(y\)完全没有用,我们先对横坐标\(x\)排序,然后从左边开始枚举,用\(l[i ...
 - Codeforces Round #667 (Div. 3)   D. Decrease the Sum of Digits   (贪心)
		
题意:给你一个正整数\(n\),每次可以对\(n\)加一,问最少操作多少次是的\(n\)的所有位数之和不大于\(s\). 题解:\(n\)的某个位置上的数进位,意味这后面的位置都可以被更新为\(0\) ...
 - Codeforces Round #667 (Div. 3)   C. Yet Another Array Restoration   (数学)
		
题意:给你两个数字\(x\)和\(y\),让你构造一个长度为\(n\)的序列,要求包含\(x\)和\(y\),并且排序后相邻两项的差值相等. 题解:有排序后相邻两项的差值相等可知,构造的序列排序后一定 ...
 - Codeforces Round #667 (Div. 3)   B. Minimum Product  (贪心,数学)
		
题意:给你\(a\)和\(b\)两个数,每次操作可以是任意一个数\(-1\),最多操作\(n\),并且\(a\ge x\),\(b\ge y\),求操作后\(a*b\)的最小值. 题解:观察样例并且在 ...
 - Codeforces Round #366 (Div. 2) ABC
		
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
 - Codeforces Round #354 (Div. 2) ABCD
		
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
 - Codeforces Round #368 (Div. 2)
		
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
 - cf之路,1,Codeforces Round #345 (Div. 2)
		
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
 
随机推荐
- Linux学习笔记 | 将默认镜像源修改为国内镜像源
			
前言: 在使用Linux操作系统的时候,难免会下载各种安装包,而Linux使用的下载源服务器属于国外,下载速度相对国内会慢很多,像日常使用的阿里云和腾讯云等国内服务器厂商,镜像源都默认为自己相关的镜像 ...
 - MySQL查询优化之 index 索引的分类和使用
			
索引的分类 主键索引 (PRIMARY KEY) 唯一的标识符, 主键不可重复, 只能有一列作为主键 唯一索引 (Unique KEY) 避免重复的列出现, 唯一索引可以重复, 多个列都可以标识为唯一 ...
 - 创建一个简单MyBatis程序
			
文章目录 MyBatis基础 MyBatis 简介 创建一个MyBatis程序 1. 创建Java项目 2. 加载MyBatis包 3. 编写POJO类和映射文件 4.创建mybatis-config ...
 - Over Permission - Pikachu
			
概述: 如果使用A用户的权限去操作B用户的数据,A的权限小于B的权限,如果能够成功操作,则称之为越权操作. 越权漏洞形成的原因是后台使用了不合理的权限校验规则导致的. 一般越权漏洞容易出现在权限页面( ...
 - ctfhub技能树—web前置技能—http协议—302跳转
			
开启靶机 打开环境,查看显示 点击Give me Flag后发生跳转 根据题目提示为HTTP临时重定向 简单记录一下HTTP临时重定向是什么 HTTP重定向:服务器无法处理浏览器发送过来的请求(req ...
 - 微服务网关2-搭建Gateway服务
			
一.创建父模块infrastructure 1.创建模块 在guli_parent下创建普通maven模块 Artifact:infrastructure 2.删除src目录 二.创建模块api_ga ...
 - QQ刷屏助手
			
本人小学生,求大佬轻点儿 制作原因 原因很简单,还不是想报仇呗! 代码 1 # 原理是先将需要发送的文本放到剪贴板中,然后将剪贴板内容发送到qq窗口 2 # 之后模拟按键发送enter键发送消息 3 ...
 - 计算机网络安全 —— 报文摘要算法 ME5 (三)
			
一.报文摘要算法基本概念 使用加密通常可达到报文鉴别的目的,因为伪造的报文解密后一般不能得到可理解的内容.但简单采用这种方法,计算机很难自动识别报文是否被篡改.另外,对于不需要保密而只需要报文鉴别的网 ...
 - java虚拟机入门(五)- 常见垃圾回收器及jvm实现
			
上节讲完了垃圾回收的基础,包括java的垃圾是什么,如何寻找以及常用的垃圾回收算法,那么那么多的理论知识讲完了,具体是什么样的东西在做着回收垃圾的事情呢?我们接下来就好好聊聊jvm中常用的垃圾回收器. ...
 - MySQL之谓词下推
			
MySQL之谓词下推 什么是谓词 在SQL中,谓词就是返回boolean值即true或者false的函数,或是隐式转换为boolean的函数.SQL中的谓词主要有 LKIE.BETWEEN.IS NU ...