写在前边

链接:Educational Codeforces Round 103 (Rated for Div. 2)

A. K-divisible Sum

链接:A题链接

题目大意:

要求构造一个\(a\)数组使得\(a\)的和可以被\(k\)整除,在这个条件下让\(a\)中的最大值尽可能小。

思路

我是这样想的,就是n张牌组成\(k\),比如要求\(4\)张牌组成\(5, 6, 7, 8\)那么数组里最大的数最小肯定是\(2\),但是如果\(8 < k \leq 12\),那么就是\(3...\)了,而对于\(n < k\)的,我们想办法先让\(k > n\),然后再与上面同理,所以我是分类讨论的:

当\(n < k\)时,那么最大的那个数就是\(k / n\),如果无法整除则需要向上取整, 即\(k / n + (k \% n == 0 ? 0 : 1)\)。

当\(k = n\)时,那么最大的数最小肯定就是\(k / n = 1\)了。

当\(n > k\)时,那么我们可以先让\(k > n\),即\(k = k * (n / k + (n \% k == 0 ? 0 : 1))\),然后就与第一种情况同理了。

看到好多被\(hack\)的代码也是用这种思路,但是没有考虑无法整除向上取整的问题。

顺便新学了一招:\(q = \lceil \cfrac{n}{k} \rceil = \lfloor \cfrac{n + k - 1}{k} \rfloor\),这样向上取整就用不着再用三目运算符啦!

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <unordered_map> using namespace std; #define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long> typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI; void solve() {
LL n, k;
cin >> n >> k;
if (n > k) {
LL t1 = n / k;
k = k * (t1 + (n % k == 0 ? 0 : 1));
LL t2 = k / n;
cout << t2 + (k % n == 0 ? 0 : 1) << '\n';
return;
} else if (k == n) {
cout << 1 << endl;
return;
} else {
LL t2 = k / n;
cout << t2 + (k % n == 0 ? 0 : 1) << '\n';
}
} int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
solve();
} return 0;
}

B. Inflation

链接:B题链接

题目大意:

修改一个序列,让其通货膨胀系数不能超过\(k%\),输出序列修改了多少。

而\(p_i\)的通货膨胀系数:\(k_i = \cfrac{p_i}{p_1 + p_2 + ... + p_{i-1}}\),求出最小的修改数。

思路

看到这个题因为枚举到后边的时候我们只关心前缀和就可以,不用具体关心前边某一个元素该怎么变化,所以就想到了前缀和,但是还是因为浮点数问题,其实类似问题已经在\(atc\)中一场比赛意识到了,遇到除法能不用小数就不用,比如判断是否合理的时候可以转化成乘法判断\(a[i] * 100 <= s[i-1] * k\),最后终于修改的差不多了,还是有一个地方没有处理好,赛后才看到一个人代码恍然大悟,除不尽的时候应该向上取整的,可惜了。

向上取整还是用这种方法:\(q = \lceil \cfrac{n}{k} \rceil = \lfloor \cfrac{n + k - 1}{k} \rfloor\)

代码:

一开始的核心代码是这样的,用数组\(s\)来维护前缀和,但是每次都要再维护一下前缀和,明显增加了时间复杂度。

void deal(int k, LL temp) {
for (int i = k; i <= n; i++) {
s[i] += temp;
}
} void solve() {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
s[i] = s[i - 1] + a[i];
}
LL sum = 0;
for (int i = 2; i <= n; i++) {
if (a[i] * 100 <= s[i-1] * k) {
continue;
} else {
LL temp = (a[i] * 100 - k * s[i-1]) / k;
temp = (a[i] * 100 - k * s[i-1]) % k == 0 ? temp : temp + 1;
sum += temp;
deal(i - 1, temp); //处理前缀和
}
} cout << sum << endl;
}

后来优化了很多,包括代码的长短,以及用一个变量来维护前缀和。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <unordered_map>
#include <cmath> using namespace std; #define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long> typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI; const int N = 110;
LL a[N];
LL n, k; void solve() {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
LL sum = 0, preSum = a[1];
for (int i = 2; i <= n; i++) {
if (a[i] * 100 > preSum * k) {
LL temp = (a[i] * 100 - k * preSum + k - 1) / k;
sum += temp;
preSum += temp;
}
preSum += a[i];
} cout << sum << endl;
} int main()
{
//ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
solve();
} return 0;
}

C. Longest Simple Cycle

链接:C题链接

题目大意:

不描述原题了,有点难描述。。

思路

因为我们求得一个圈的长度,而一个圈的右边必然右一条链组成,所以我们从第二条链往后枚举每一条链,对于每一个圈的右半部分长度就是\(c[i] + 1\),而对于左半部分,如果\(a_i == b_i\)那么就说明右半部分重合到一点了,否则就是\(abs(a_i - b_i)\),维护一个\(curlen\)以及一个\(lastlen\),对于\(a_i != b_i\)的时候,我们可以判断一下左边的环与右边的环接起来是否会更大,如果更大就把中间的\(abs(a_i - b_i)\)去掉,即\(curlen = max(curlen, c[i] + 1 + lastlen - abs(a[i] - b[i]))\),然后更新\(res\)以及\(lastlen\)即可

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <unordered_map> using namespace std; #define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long> typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI; const int N = 2e5 + 10;
LL c[N], a[N], b[N]; void solve() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> c[i];
}
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n; i++) {
cin >> b[i];
}
LL res = 0, curlen = 0, lastlen = 0;
for (int i = 1; i < n; i++) {
curlen = c[i] + 1 + abs(a[i] - b[i]);
if (a[i] != b[i]) {
curlen = max(curlen, c[i] + 1 + lastlen - abs(a[i] - b[i]));
}
res = max(res, curlen);
lastlen = curlen;
}
cout << res << endl;
} int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
solve();
} return 0;
}

D. Journey

链接:D题链接

题目大意:

给定一组\(n\)个道路的方向,链接了\(n + 1\)个城市,旅游时只能按照道路方向旅游,同时走一次道路那么所有的道路就反向一次,比如原来道路方向只能是\(A->B\),但是到\(B\)之后道路会反向,所以然后还可以从\(B\)返回\(A\),求从每一个城市可以旅行到的最多城市。

思路

一种是利用本题的性质,因为去还可以回来,所以可以说是一种无向边,但是并查集(\(DSU\)),\(BFS\),\(DFS\)代码我看了一上午,实在看不懂,想不明白。

于是用递推的方式做了,即用\(dpl_i\)表示\(i\)城市从\(i\)城市向左可以最多走到的城市标号,用\(dpr_i\)表示从\(i\)城市向右可以最多走到的城市标号,最后答案就是\(num_i = dpr_i -dpl_i +1\),只不过要注意的细节比较多。

对于\(dpl_i\):

  1. 如果不能向左走,那么:\(dpl_i = i\)。
  2. 如果能向左走一步那么:\(dpl_i = i-1\)
  3. 然后就可以直接转移了:\(dpl_i = dpl_{i-2}\)

    对于\(dpr_i\)同理,从后向前递推即可。

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector> using namespace std; #define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n' typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI; const int N = 3E5 + 10;
char s[N];
int n;
int dpl[N], dpr[N]; void solve() {
scanf("%d", &n);
scanf("%s", s + 1);
for (int i = 1; i <= n + 1; i++) {
dpl[i] = i;
}
for (int i = 1; i <= n + 1; i++) {
dpr[i] = i;
}
for (int i = 1; i <= n + 1; i++) {
if (i == 1 || s[i - 1] == 'R') { //向左走不动
dpl[i] = i;
} else if (i == 2 || s[i - 2] == 'L') { //向左只能走一格
dpl[i] = i - 1;
} else {
dpl[i] = dpl[i - 2];
}
}
for (int i = n + 1; i >= 1; i--) {
if (i == n + 1 || s[i] == 'L') {
dpr[i] = i;
} else if (i == n || s[i + 1] == 'R') {
dpr[i] = i + 1;
} else {
dpr[i] = dpr[i + 2];
}
}
for (int i = 1; i <= n + 1; i++) {
printf("%d ", dpr[i] - dpl[i] + 1);
}
puts("");
} int main()
{
//ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t;
scanf("%d", &t);
while (t--) {
solve();
} return 0;
}

Educational Codeforces Round 103 (Rated for Div. 2) A~D题解的更多相关文章

  1. Educational Codeforces Round 61 (Rated for Div. 2) D,F题解

    D. Stressful Training 题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有n台电脑,每台电脑都有初始电量ai,也有一个 ...

  2. Educational Codeforces Round 81 (Rated for Div. 2) A-E简要题解

    链接:https://codeforces.com/contest/1295 A. Display The Number 贪心思路,尽可能放置更多位,如果n为奇数,消耗3去放置一个7,剩下的放1 AC ...

  3. 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 ...

  4. 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 ...

  5. Educational Codeforces Round 43 (Rated for Div. 2)

    Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...

  6. Educational Codeforces Round 35 (Rated for Div. 2)

    Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...

  7. 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 ...

  8. 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 ...

  9. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  10. 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 < ...

随机推荐

  1. Fastjson1.2.24漏洞复现-基于vulhub漏洞平台(文件上传写入-反弹shell)

    Fastjson1.2.24漏洞复现-基于vulhub漏洞平台 环境准备: 192.168.59.130 攻击机 window10 192.168.59.135 靶机 centos8 声明:不涉及互联 ...

  2. Typescript:基础语法学习(尚硅谷 李立超)

    官方文档:https://www.tslang.cn/docs/handbook/typescript-in-5-minutes.html 搭建开发环境 npm i -g typescript安装完成 ...

  3. Print, printf, println的区别

    print 非格式,打印变量的值,不换行 printf 支持格式化输出,不换行 println 非格式,打印变量的值 ,换行

  4. 如何配置Linux的互信

    如何配置Linux的互信? 这里针对的是root用户的,普通用户家目录/home/test/.ssh. 1.在客户端生成公钥私钥对 [root@auto1 ~]# ssh-keygen -t rsa ...

  5. java file I/O流

    一.File的简介:(java.io包) 生活中的文件: (1)文件的作用:持久化(瞬时状态的对立面状态) (1)文件的定义:一堆数据的集合 (2)文件存储的位置:磁盘,硬盘,软盘,U盘等等 计算机中 ...

  6. 2.0 Python 数据结构与类型

    数据类型是编程语言中的一个重要概念,它定义了数据的类型和提供了特定的操作和方法.在 python 中,数据类型的作用是将不同类型的数据进行分类和定义,例如数字.字符串.列表.元组.集合.字典等.这些数 ...

  7. HDU 3829 Cat VS Dog 猫和狗(二分图)结题报告

    听学长说这道题很ex,但是思路想到的话还是挺简单的. 可能是受上一道题(放置机器人)的启发,也是找互相冲突的点连线. 但是并不是完全一样(废话)放置机器人那道题是找到冲突点连线后直接求最大匹配即可. ...

  8. 论文解读(AdSPT)《Adversarial Soft Prompt Tuning for Cross-Domain Sentiment Analysis》

    Note:[ wechat:Y466551 | 可加勿骚扰,付费咨询 ] 论文信息 论文标题:Adversarial Soft Prompt Tuning for Cross-Domain Senti ...

  9. OpenLDAP 自助修改密码系统

    一.创建docker-compose文件 root@xx:~# mkdir self-service-password root@xx:~# cd self-service-password root ...

  10. Mysql基础篇-查询、函数、多表、事务

    1. 基础篇 1.1 mysql用户和权限管理 查询用户 USER mysql; SELECT * FROM user; 创建用户 CREATE USER '用户名'@'主机名' IDENTIFIED ...