AtCoder Beginner Contest 329 (ABC329)
A. Spread
不说了,代码。
B. Next
不说了,代码。
C. Count xxx
Description
给定一个长度为 \(N\) 的字符串 \(S\),求 \(S\) 中非空连续,并且包含重复字符的连续子串长度。
例如 $S = $ aaabaa
,则它满足上述条件子串为 a
,aa
,aaa
,b
。
Solution
这道题 \(1 \le N \le 2 \times 10 ^ 5\),显然不能暴力。
考虑如何优化。
维护数组 \(v\),\(v_i\) 表示 \(S\) 中子串的重复字符为 \(i\) 的子串长度。
我们循环这个字符串,记录两个变量 lstc
,lstnum
,分别表示字符串 \(S\) 的上一个字符,和当前连续子串的长度。
如果我们发现,s[i] == lstc
,则 lstnum++
。否则,lstnum = 1
,lstc = s[i]
。
每次循环 v[lstc] = max(v[lstc],lstnum)
。
最后循环字符 a ~ z
,累加 \(v_i\) 即可。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, ans, v[300];
char s[N];
int main() {
scanf("%d", &n);
scanf("%s", s + 1);
char lstc = 0;
int lstnum = 0;
for (int i = 1; i <= n; ++i) {
if (s[i] == lstc) {
++lstnum;
} else {
lstnum = 1;
lstc = s[i];
}
v[lstc] = max(v[lstc], lstnum);
}
int ans = 0;
for (int i = 'a'; i <= 'z'; ++i) {
ans += v[i];
}
printf("%d", ans);
return 0;
}
D. Election Quick Report
Description
有 \(N\) 个人,编号 \(1 \sim N\)。每次会将票投给某一个人,输出投票后票数最大值的人的编号。如果票数相同,输出编号小的。
Solution
每次记录一个桶,动态维护当前票数的最大值,位置即可。
如果当前的票数大于最大值,或者当前票数等于最大值但是编号小于最大值,则讲最大值更改为当前的票数,并且将位置更改为当前的位置。
每次询问输出位置即可。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m, a[N], cnt[N], ma = 0, p;
int main() {
cin >> n >> m;
for (int i = 1; i <= m; i++) {
scanf("%d", &a[i]);
cnt[a[i]]++;
if (cnt[a[i]] > ma || (cnt[a[i]] == ma && a[i] < p)) {
ma = cnt[a[i]];
p = a[i];
}
printf("%d\n", p);
}
return 0;
}
E. Stamp
Description
有两个字符串 \(S\) 和 \(T\),还有一个长度为 \(N\) 的仅由字符 #
构成的字符串 \(X\)。
现在可以执行若干次操作,每次可以选择字符串 \(X\) 中连续的 \(M\) 段覆盖为 \(T\)。
求:是否能通过若干次操作,使得 \(X\) 和 \(S\) 相等。
Solution
考虑一个覆盖时间的序列(钦定每一次覆盖记录在其右端点上),发现对于当前点 \(p\):
只有 \([p,p+m-1]\) 这一段区间会影响该点的取值,考虑爆搜,对于当前位置p,只需要考虑 \([p-m+1,p]\) 这一段长度为m的时间序列,枚举当前一个新的位置的相对时间排名,确定下来 \([p-m+1,p]\) 的相对时间顺序,于是位置 \(p-m+1\) 的值会被 \([p-m+1,p]\) 中时间值最大的点覆盖掉,再判断 \(p-m+1\) 的值是否与 \(S\) 串对应位置相等即可。
考虑优化:当前状态包含当前位置 \(p\),和前面的时间序列 \(st\),若之前已经走到过 <p,st>
这样一个状态,那当前就没必要继续往下搜了。
Code
#include <bits/stdc++.h>
using namespace std;
unordered_map<int, int> mp;
int n, m;
int gethash(int now, int stat[5]) {
int hsh = now;
for (int i = 0; i < m - 1; i++) hsh = hsh * m + stat[i];
return hsh;
}
char s[200055];
char t[55];
bool search(int now, int stat[5]) {
int hsh = gethash(now, stat);
if (mp.find(hsh) != mp.end()) return false;
mp[hsh] = 1;
if (now == n + 1) {
char x[6];
for (int j = 1; j < m; j++) {
for (int k = 0; k < m - 1; k++) {
if (stat[k] == j) {
for (int l = 2; l <= m - k; l++) {
x[l] = t[l + k];
}
}
}
}
for (int i = 2; i <= m; i++) if (s[n + i - m] != x[i]) return false;
return true;
}
for (int i = 1; i <= m; i++) {
int new_stat[5];
new_stat[0] = i;
for (int j = 1; j < m; j++) {
new_stat[j] = stat[j - 1];
if (stat[j - 1] >= i) ++new_stat[j];
}
bool flag = true;
for (int j = 0; j < m; j++) {
if (new_stat[j] == m) {
if (s[now - m + 1] != t[j + 1]) flag = false;
}
}
if (!flag) continue;
for (int j = 0; j < m - 1; j++) {
if (new_stat[j] > new_stat[m - 1]) --new_stat[j];
}
if (search(now + 1, new_stat)) return true;
}
return false;
}
int stat[5];
int main() {
cin >> n >> m;
scanf("%s%s", s + 1, t + 1);
if (s[1] != t[1]) {
puts("No");
return 0;
}
for (int i = 0; i < 5; i++) stat[i] = m - i - 1;
if (search(m + 1, stat)) {
printf("Yes");
return 0;
}
printf("No");
return 0;
}
F. Colored Ball
Description
有 \(N\) 个箱子,编号为 \(1 \sim N\)。每个箱子初始有一个小球,颜色为 \(C_i\)。
现在有 \(Q\) 次询问,每次输入一个二元组 \((a,b)\),表示将编号为 \(a\) 的箱子里的所有小球移动到箱子 \(b\) 后,询问箱子 \(b\) 中有多少种不同颜色的小球。
Solution
这道题用 set
的暴力模拟法,时间复杂度约为 \(O(n ^ 2 \times \log n)\),肯定超时。
可以加上优化:set
的启发式合并。
即每次将小的箱子移动到大的箱子里面,这样花费的时间会大大减少,时间复杂度达到了 \(O(n)\)。
只需要在代码中加入一句话:
if (st[x].size() > st[y].size()) swap(st[x], st[y]);
这样就实现了启发式合并,可以通过。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int n, q, a[N], x, y;
unordered_set<int> st[N];
int main() {
cin >> n >> q;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
st[i].insert(a[i]);
}
while (q--) {
scanf("%d%d", &x, &y);
if (st[x].size() > st[y].size()) swap(st[x], st[y]);
while (st[x].size()) {
int t = *st[x].begin();
st[x].erase(t);
st[y].insert(t);
}
printf("%d\n", (int)st[y].size());
}
return 0;
}
AtCoder Beginner Contest 329 (ABC329)的更多相关文章
- AtCoder Beginner Contest 100 2018/06/16
A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...
- AtCoder Beginner Contest 052
没看到Beginner,然后就做啊做,发现A,B太简单了...然后想想做完算了..没想到C卡了一下,然后还是做出来了.D的话瞎想了一下,然后感觉也没问题.假装all kill.2333 AtCoder ...
- AtCoder Beginner Contest 053 ABCD题
A - ABC/ARC Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Smeke has ...
- AtCoder Beginner Contest 136
AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...
- AtCoder Beginner Contest 137 F
AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...
- AtCoder Beginner Contest 076
A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...
- AtCoder Beginner Contest 079 D - Wall【Warshall Floyd algorithm】
AtCoder Beginner Contest 079 D - Wall Warshall Floyd 最短路....先枚举 k #include<iostream> #include& ...
- AtCoder Beginner Contest 064 D - Insertion
AtCoder Beginner Contest 064 D - Insertion Problem Statement You are given a string S of length N co ...
- AtCoder Beginner Contest 075 D - Axis-Parallel Rectangle【暴力】
AtCoder Beginner Contest 075 D - Axis-Parallel Rectangle 我要崩溃,当时还以为是需要什么离散化的,原来是暴力,特么五层循环....我自己写怎么都 ...
- AtCoder Beginner Contest 075 C bridge【图论求桥】
AtCoder Beginner Contest 075 C bridge 桥就是指图中这样的边,删除它以后整个图不连通.本题就是求桥个数的裸题. dfn[u]指在dfs中搜索到u节点的次序值,low ...
随机推荐
- JDBC:使用IDEA配置JDBC
IDEA使用Jar包 操作流程 步骤1:创建lib路径 步骤2:复制jar包 步骤3:必须要做的一步 参考链接 https://blog.csdn.net/upup1006/article/detai ...
- jQuery事件冒泡和默行为
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- OpenUSD联盟:塑造元宇宙的3D未来
一.引言 近日,美国3D内容行业的五家主要公司苹果.英伟达.皮克斯.Adobe和Autodesk联合成立了OpenUSD联盟(AOUSD).这一联盟的成立标志着元宇宙领域的一次重要合作,旨在制定元宇宙 ...
- Unity Shader编辑器工具类ShaderUtil 常用函数和用法
Unity Shader编辑器工具类ShaderUtil 常用函数和用法 Unity的Shader编辑器工具类ShaderUtil提供了一系列函数,用于编译.导入和管理着色器.本文将介绍ShaderU ...
- 常见的 NoSQL 数据库有哪些?
前言 今天我们来介绍一下工作开发中常见的一些NoSQL数据库及其基本特点.欢迎在评论区留下文章中没有介绍且好用的NOSQL数据库. 什么是NOSQL数据库 非关系型数据库又被称为 NoSQL(Not ...
- 2023-08-06:小青蛙住在一条河边, 它想到河对岸的学校去学习 小青蛙打算经过河里 的石头跳到对岸 河里的石头排成了一条直线, 小青蛙每次跳跃必须落在一块石头或者岸上 给定一个长度为n的数组ar
2023-08-06:小青蛙住在一条河边, 它想到河对岸的学校去学习 小青蛙打算经过河里 的石头跳到对岸 河里的石头排成了一条直线, 小青蛙每次跳跃必须落在一块石头或者岸上 给定一个长度为n的数组ar ...
- NFS快速入门(一):简介、原理
NFS网络文件共享存储 什么是NFS NFS 是 Network File System 的缩写,中文意思是网络文件系统.它的主要功能是通过网络(一般是局域网)让不同主机系统之间可以共享文件或目录.N ...
- 文心一言 VS 讯飞星火 VS chatgpt (72)-- 算法导论7.1 3题
三.请简要地证明:在规模为 n 的子数组上,PARTITION 的时间复杂度为 Θ(n). 文心一言: 首先,我们需要明确PARTITION函数的具体定义.PARTITION函数通常用于快速排序算法中 ...
- 使用canvas(2d)+js实现一个简单的傅里叶级数绘制方波图
先看效果 查看页面右下角,嘿嘿 简要说明 创建具有不同半径与角速度的圆集合:(截图中展现的效果为5个,代码是30个,运行后效果会不同) const getCircles = (N = 10) => ...
- 使用Java来开发物联网应用
这是Hello, Lithosphere Tutorials系列教程中的其中一篇. 感觉介绍用C/C++,用Python来开发物联网应用的文章比较多,用Java来做物联网的文章比较少. 这篇文章,介绍 ...