比赛链接

A

题解

知识点:模拟

时间复杂度 \(O(1)\)

空间复杂度 \(O(1)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; bool solve() {
int a, b, c;
cin >> a >> b >> c;
int x = a - 1;
int y = abs(b - c) + c - 1;
if (x > y) cout << 2 << '\n';
else if (x < y) cout << 1 << '\n';
else cout << 3 << '\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;
}

B

题解

知识点:模拟。

倒着来,很方便。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; bool solve() {
int n;
cin >> n;
string T;
cin >> T;
string S;
for (int i = T.length() - 1;i >= 0;i--) {
if (T[i] == '0') {
S = (char)((T[i - 1] - '0') + (T[i - 2] - '0') * 10 + 'a' - 1) + S;
i -= 2;
}
else {
S = (char)(T[i] - '0' + 'a' - 1) + S;
}
}
cout << S << '\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;
}

C

题解

知识点:贪心,枚举。

显然最小花费是 \(|s[n]-a[1]|\) ,最大化路线的方式是按序走过 \(s[1]\) 到 \(s[n]\) 的所有字母。

把每个字母的下标放进桶中 , \(s[1]\) 比 \(s[n]\) 小则从 \(s[1]\) 正序,否则从 \(s[1]\) 倒序。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; bool solve() {
string s;
cin >> s;
int n = s.length();
s = "?" + s;
vector<vector<int>> v(26);
for (int i = 1;i <= n;i++) {
v[s[i] - 'a'].push_back(i);
}
int x = s[1] - 'a', y = s[n] - 'a';
if (x < y) {
int cnt = 0;
for (int i = x;i <= y;i++) {
cnt += v[i].size();
}
cout << abs(s[n] - s[1]) << ' ' << cnt << '\n';
for (int i = x;i <= y;i++)
for (auto j : v[i]) cout << j << ' ';
}
else {
int cnt = 0;
for (int i = x;i >= y;i--) {
cnt += v[i].size();
}
cout << abs(s[n] - s[1]) << ' ' << cnt << '\n';
for (int i = x;i >= y;i--)
for (auto j : v[i]) cout << j << ' ';
}
cout << '\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

题解

知识点:贪心,枚举,双指针。

处理出 \(y-x\) 得到每个成员的贡献,从小到大排序,最小的和最大的两人一组即可最大化分组数量,不能分配就跳过较小的。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; int diff[100007];
bool solve() {
int n;
cin >> n;
for (int i = 1;i <= n;i++) cin >> diff[i];
for (int i = 1;i <= n;i++) {
int y;
cin >> y;
diff[i] = y - diff[i];
}
sort(diff + 1, diff + n + 1);
int ans = 0;
int l = 1, r = n;
while (l < r) {
if (diff[l] + diff[r] >= 0) ans++, r--;
l++;
}
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

题解

知识点:贪心。

\(i\) 从 \(2\) 开始依次询问。先询问 \((1,i)\) ,如果结果 \(-1\) 则输出 \(i-1\) ;否则,再询问一次 \((i,1)\) ,如果答案和 \((1,i)\) 不同则输出两个答案之和,否则继续下一个 \(i\) 。除去特判 \(n \in [3,25]\) 会因为询问到 \(-1\) 结束的情况,其他情况只需要一组答案不同即可,概率很高。

时间复杂度 \(O(1)\)

空间复杂度 \(O(1)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; ll query(ll a, ll b) {
cout << "? " << a << ' ' << b << endl;
ll ans;
cin >> ans;
return ans;
} void answer(ll x) {
cout << "! " << x << endl;
exit(0);
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
for (int i = 2;i;i++) {
ll ans1 = query(1, i);
if (!~ans1) answer(i - 1);
ll ans2 = query(i, 1);
if (ans1 != ans2) answer(ans1 + ans2);
}
return 0;
}

F

题解

知识点:枚举,前缀和,数论。

注意到一个数字 \(\mod 9\) 的答案和所有数位加起来 \(\mod 9\) 的答案相同,因此先对 \(s\) 数位预处理模意义前缀和。

然后处理出所有 \(w\) 长度的串的余数,把串首坐标放进桶中对应余数的位置,只需要存两个最左边的即可。

对于每组询问,遍历余数 \(a,b\) 满足 \(a \cdot re + b \equiv k \pmod 9\) ,其中 \(re\) 为 \([l,r]\) 的余数。将余数 \(a,b\) 对应的串下标更新一下答案即可,答案可以用 pair 存,方便更新。注意特判 \(a = b\) 的情况,需要同一个余数的前两个下标。

时间复杂度 \(O(n+m)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; int a[200007];
bool solve() {
string s;
cin >> s;
int n = s.length();
s = "?" + s;
for (int i = 1;i <= n;i++) a[i] = (s[i] - '0' + a[i - 1]) % 9;
int w, m;
cin >> w >> m;
vector<vector<int>> pos(9);
for (int i = w;i <= n;i++) {
int re = (a[i] - a[i - w] + 9) % 9;
if (pos[re].size() < 2) pos[re].push_back(i - w + 1);
}
while (m--) {
int l, r, k;
cin >> l >> r >> k;
int re = (a[r] - a[l - 1] + 9) % 9;
pair<int, int> ans = { n + 1,n + 1 };
for (int i = 0;i <= 8;i++) {
if (pos[i].empty()) continue;
for (int j = 0;j <= 8;j++) {
if (pos[j].empty()) continue;
if ((i * re + j) % 9 == k) {
if (i != j) ans = min(ans, { pos[i][0],pos[j][0] });
else if (i == j && pos[i].size() == 2) ans = min(ans, { pos[i][0],pos[i][1] });
}
}
}
if (ans > pair<int, int>{n, n}) cout << -1 << ' ' << -1 << '\n';
else cout << ans.first << ' ' << ans.second << '\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;
}

G

题解

知识点:线性dp。

预处理出 \(s\) 中所有能删除 \(t\) 的下标,暴力 \(O(n^2)\) 处理即可,存进 vector 。随后dp一下前 \(i\) 个能删除位置的最小删除次数。

设 \(f[i]\) 为考虑到第 \(i\) 个能删除的位置,删除 \([1,v[i]]\) 所有能删除的段,且一定删除第 \(i\) 段的最小删除次数。设 \(tot[i]\) 为能够达成 \(f[i]\) 删除次数的对应的方案数。

对于 \(v[i]\) ,我们枚举上一个删除的位置 \(v[j]\) ,先保证 \(i,j\) 不重合即 \(v[i]-v[j]\geq m\) ,然后保证 \(i,j\) 中间没有别的能删除的段即 $v[k] - v[j] < m $ 以及 $ v[i] - v[k] < m$ 。于是可以转移:

if (f[i] > f[j] + 1) {
f[i] = f[j] + 1;
tot[i] = tot[j];
}
else if (f[i] == f[j] + 1) {
tot[i] = (tot[i] + tot[j]) % mod;
}

最后统计末尾重合的一段的最小删除次数,以及对应的总方案数。

时间复杂度 \(O(nm^2)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; const int mod = 1e9 + 7; bool solve() {
string s, t;
cin >> s >> t;
int n = s.size(), m = t.size();
s = "?" + s;
vector<int> v;
v.push_back(0);
for (int i = m;i <= n;i++)
if (s.substr(i - m + 1, m) == t) v.push_back(i);
vector<int> f(507, 0x3f3f3f3f), tot(507, 0);
f[0] = 0, tot[0] = 1;
for (int i = 1;i < v.size();i++) {
for (int j = i - 1;j >= 0;j--) {
if (v[i] - v[j] < m) continue;
bool ok = 1;
for (int k = j + 1;k < i;k++) ok &= v[k] - v[j] < m || v[i] - v[k] < m;
if (!ok) break;
if (f[i] > f[j] + 1) {
f[i] = f[j] + 1;
tot[i] = tot[j];
}
else if (f[i] == f[j] + 1) {
tot[i] = (tot[i] + tot[j]) % mod;
}
}
}
int mi = n, ans = 0;
for (int i = 0;i < v.size();i++) if (v.back() - v[i] < m) mi = min(mi, f[i]);
for (int i = 0;i < v.size();i++) if (v.back() - v[i] < m && f[i] == mi) ans = (ans + tot[i]) % mod;
cout << mi << ' ' << 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;
}

Codeforces Round #820 (Div. 3) A-G的更多相关文章

  1. Educational Codeforces Round 47 (Div 2) (A~G)

    目录 Codeforces 1009 A.Game Shopping B.Minimum Ternary String C.Annoying Present D.Relatively Prime Gr ...

  2. Educational Codeforces Round 46 (Div 2) (A~G)

    目录 Codeforces 1000 A.Codehorses T-shirts B.Light It Up C.Covered Points Count(差分) D.Yet Another Prob ...

  3. Educational Codeforces Round 45 (Div 2) (A~G)

    目录 Codeforces 990 A.Commentary Boxes B.Micro-World C.Bracket Sequences Concatenation Problem D.Graph ...

  4. Codeforces Round #582 (Div. 3)-G. Path Queries-并查集

    Codeforces Round #582 (Div. 3)-G. Path Queries-并查集 [Problem Description] 给你一棵树,求有多少条简单路径\((u,v)\),满足 ...

  5. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  6. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  7. 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts

    题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...

  8. Codeforces Round #383 (Div. 2) 题解【ABCDE】

    Codeforces Round #383 (Div. 2) A. Arpa's hard exam and Mehrdad's naive cheat 题意 求1378^n mod 10 题解 直接 ...

  9. 模拟 Codeforces Round #249 (Div. 2) C. Cardiogram

    题目地址:http://codeforces.com/contest/435/problem/C /* 题意:给一组公式,一组数据,计算得到一系列的坐标点,画出折线图:) 模拟题:蛮恶心的,不过也简单 ...

随机推荐

  1. 第八十五篇:Vue购物车(六) 总价的动态计算

    好家伙, 1.实现总价的动态计算 商品数量被动态的改变后, 相应的总价同样会改变 所以我们需要重新计算总价格了 这个的实现并不难 我只要拿到商品的数量就好了 我们用一个计算属性计算出已勾选商品的总数量 ...

  2. Python入门系列(十一)一篇搞定python操作MySQL数据库

    开始 安装MySQL驱动 $ python -m pip install mysql-connector-python 测试MySQL连接器 import mysql.connector 测试MySQ ...

  3. web前端小知识 —— 【HTML,CSS,JS】集锦 【第一期】 { }

    1.获取元素样式属性的方法 第 一 种 : 较灵活,能获取传进来想获取的元素的样式属性,返回的是[字符串] function getStyle(obj, name) { // IE // 主流 ret ...

  4. torch.sort 和 torch.argsort

    定义 torch.sort(input,dim,descending) torch.argsort(input,dim,descending) 用法 torch.sort:对输入数据排序,返回两个值, ...

  5. dotnet7 aot编译实战

    0 起因 这段日子看到dotnet7-rc1发布,我对NativeAot功能比较感兴趣,如果aot成功,这意味了我们的dotnet程序在防破解的上直接指数级提高.我随手使用asp.netcore-7. ...

  6. redhat替换yum源时redhat.repo无法删除或禁用的问题

    rhel7.3系统,在替换自带的repo源时发现无论是将redhat.repo重命名还是删除,在执行yum命令后总是自动又生成redhat.repo得问题,导致替换的CentOS-Base.repo, ...

  7. 生产环境中使用Kibana

    在 Kibana 中使用 X-Pack 使用 X-Pack 安全模块 控制用户通过 Kibana 可以访问哪些 Elasticsearch 数据. 当安装 X-Pack 时,Kibana 用户必须登陆 ...

  8. Elasticsearch的mapping讲解

    映射是定义文档及其包含的字段的存储和索引方式的过程. 映射定义具有: 元字段 元字段用于自定义如何处理关联的文档元数据.包括文档 _index,_id和 _source领域. 字段或属性 映射包含pr ...

  9. 7.nexus版本升级

    nexus-3.14.0升级到3.15.2 首先来看下原来的服务目录: nexus-3.14.0-04 sonatype-work 注意:nexus-3.14.0-04是应用程序包,sonatype- ...

  10. (Bug修复)C#爬虫,让你不再觉得神秘

    Bug修复 https://github.com/ZhangQueque/quewaner.Crawler/issues/1 修复加载Https网址中午乱码,导致Node解析失败的问题 1.使用第三方 ...