ABC346 A-G 题解

ABC346 A-G题解

  • A
    • 题目
    • AC Code:
    • 时间复杂度
  • B
    • 题目
    • 时间复杂度
    • AC Code:
  • C
    • 题目
    • 时间复杂度
    • AC Code:
  • D
    • 题目
    • 时间复杂度
    • AC Code:
  • E
    • 题目
    • 时间复杂度
    • AC Code:
  • F
    • 题目
    • 时间复杂度
    • AC Code:
  • G
    • 题目
    • 时间复杂度
    • AC Code:

下面的内容不包括题目翻译,要想获取题目翻译,请参照 这篇教程 来获取题目翻译。

A

题目

循环处理每一个数字即可,不再赘述。

AC Code:

#include <iostream>
using namespace std;
int n, a[200100];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i < n; i++) cout << a[i] * a[i + 1] << ' ';
	return 0;
}

时间复杂度

O ( N ) O(N) O(N)

B

题目

由于键盘是有规律的,所以任何子串都可以从从 12 12 12 以内开始的子串提取出来。暴力即可, 200 200 200 够用了。

时间复杂度

O ( 20 0 2 ) O(200^2) O(2002)

AC Code:

#include <iostream>
#include <cstring>
using namespace std;
int w, b;
string s = "wbwbwwbwbwbw";
string s1;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> w >> b;
	for (int i = 0; i <= 20; i++) {
		for (int j = 0; j < (int)s.length(); j++) {
			s1.push_back(s[j]);
		}
	}
	for (int i = 0; i < (int)s1.size(); i++) {
		int cntw = 0, cntb = 0;
		for (int j = i; j < (int)s1.size(); j++) {
			if (w == cntw && b == cntb) {
				cout << "Yes\n";
				return 0;
			}
			if (s1[j] == 'b') cntb++;
			else cntw++;
		}
	}
	cout << "No";
	return 0;
}

C

题目

我们发现,与其一个一个找没有出现在 A A A 里面的数,不如从小于等于 K K K 的所有数字里面寻找在 A A A 里出现过的数字。我们使用一个 map 记录这个数字有没有被去除。对于每一个 A i A_i Ai,如果 A i ≤ K A_i \le K AiK 且没有被去除,就从所有小于等于 K K K 的数字的和里面减去这个数字,把这个数字标记为已去除。

时间复杂度

O ( N log ⁡ ( 1 0 9 ) ) O(N\log(10^9)) O(Nlog(109))

AC Code:

#include <iostream>
#include <map>
using namespace std;
int n;
long long k, a[200100];
long long ans;
map<long long, bool> m;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> k;
	ans = (k + 1ll) * k / 2ll;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		if (!m[a[i]] && a[i] <= k) {
			ans -= a[i];
			m[a[i]] = 1;
		}
	}
	cout << ans;
	return 0;
}

D

题目

我们发现,一个好字串无非就是可以从某个位置切成两个字串,字串里相邻两个字符不一样,字串切开的位置的字符相同。

我们计算前缀后缀以 01 开始的相邻两个字符不一样的代价,即使这个字串变为 10101... 的代价。对于每一个分割点,如果原串长度是偶数,那么这两个分割后的字串另外一边要一样,否则,不一样。计算代价,取最小值即可。

时间复杂度

O ( N ) O(N) O(N)

AC Code:

#include <algorithm>
#include <iostream>
using namespace std;
int n;
char s[200100];
int c[200100];
long long sum[200100];
long long c00[200100], c01[200100], c10[200100], c11[200100];
long long ans = 1e18;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> s[i];
	for (int i = 1; i <= n; i++) cin >> c[i];
	for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + c[i];
	for (int i = 1; i <= n; i++) {
		c00[i] = c00[i - 1] + ((i - 1) % 2 == s[i] - '0') * c[i];
		c01[i] = c01[i - 1] + (i % 2 == s[i] - '0') * c[i];
	}
	for (int i = n; i >= 1; i--) {
		c10[i] = c10[i + 1] + ((n - i) % 2 == s[i] - '0') * c[i];
		c11[i] = c11[i + 1] + ((n - i + 1) % 2 == s[i] - '0') * c[i];
	}
	for (int i = 1; i < n; i++) {
		if (n % 2 == 0) {
			ans = min({ans, c00[i] + c10[i + 1], c01[i] + c11[i + 1]});
		}
		else {
			ans = min({ans, c01[i] + c10[i + 1], c00[i] + c11[i + 1]});
		}
	}
	cout << ans;
	return 0;
}

E

题目

我们倒着考虑所有操作,对于每一个横排操作,如果之前(指更晚的操作)把这一排覆盖了,那么跳过这个操作,否则统计没被覆盖的列数,该颜色数量加上这个值,把这一排标记为操作了,剩余横排数量减一,结束。
如果这是一个竖列操作,如果这一列没有被覆盖,该颜色数量加上没被覆盖的横排数,把这一列标记为被覆盖,没被覆盖的列数减去一,结束。

时间复杂度

O ( 1 ) O(1) O(1)

AC Code:

#include <iostream>
#define int long long
using namespace std;
int h, w;
int m;
int t[200100], a[200100], x[200100];
int c_h, c_w;
int cnt[200100];
int cnt1;
bool vis_h[200100], vis_w[200100];

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> h >> w;
	cin >> m;
	c_h = h, c_w = w;
	for (int i = m; i >= 1; i--) cin >> t[i] >> a[i] >> x[i];
	for (int i = 1; i <= m; i++) {
		if (t[i] == 1) {
			if (c_h && !vis_h[a[i]]) {
				c_h--;
				cnt[x[i]] += c_w;
				vis_h[a[i]] = 1;
			}
		}
		else {
			if (c_w && !vis_w[a[i]]) {
				c_w--;
				cnt[x[i]] += c_h;
				vis_w[a[i]] = 1;
			}
		}
	}
	cnt[0] += c_h * c_w;
	for (int i = 0; i <= 200000; i++) {
		if (cnt[i]) cnt1++;
	}
	cout << cnt1 << '\n';
	for (int i = 0; i <= 200000; i++) {
		if (cnt[i]) {
			cout << i << ' ' << cnt[i] << '\n';
		}
	}
	return 0;
}

F

题目

如果重复三次的情况可以,那么二次,一次的情况也可以。如果重复四次的情况不可以,重复五次,六次也不可以。可以看出这东西满足单调性,可以二分。

我们判断这个情况可不可以时,如果暴力在重复 N N N 次的串中寻找的话, N N N 很大,会爆炸。我们记录现在找到了重复第几遍的串中的第几个字符,分情况讨论找完后会不会跳到下一遍即可。如果跳不到下一遍,找到刚刚好重复我们要重复的次数的位置,否则,让总共要重复的次数除以这一边中字符个数就是要重复的次数,还要考虑这个坐标多的次数。

如果重复了 N + 1 N+1 N+1 边才找完或没找完,就说明不行。

细节很多,考验你的调试技术。

时间复杂度

O ( ∣ T ∣ log ⁡ ( N ∣ S ∣ ) ) O(|T|\log(N|S|)) O(Tlog(NS))

AC Code:

#include <iostream>
#define int long long

using namespace std;
int n;
string s, t;
int cnt[200100][50];
int idx[200100][50];
bool check(int x) {
	int now1 = 0, now2 = 0;
	for (int i = 0; i < (int)t.size(); i++) {
		if (!cnt[0][t[i] - 'a']) return 0;
		if (cnt[now2][t[i] - 'a'] >= x) {
			int tmp = x;
			if (now2) tmp += cnt[0][t[i] - 'a'] - cnt[now2][t[i] - 'a'];
			now2 = idx[tmp][t[i] - 'a'] + 1;
		}
		else {
			int tmp = x;
			tmp -= cnt[now2][t[i] - 'a'];
			now1++;
			now2 = 0;
			if (cnt[0][t[i] - 'a'] >= tmp) {
				now2 = idx[tmp][t[i] - 'a'] + 1;
			}
			else {
				now1 += tmp / cnt[0][t[i] - 'a'];
				now2 = idx[tmp % cnt[0][t[i] - 'a']][t[i] - 'a'] + 1;
				if (tmp % cnt[0][t[i] - 'a'] == 0) {
					now1--;
					now2 = idx[cnt[0][t[i] - 'a']][t[i] - 'a'];
				}
			}
		}
		now1 += now2 / (int)s.size();
		now2 %= (int)s.size();
		if (now1 > n || (now1 == n && now2)) return 0;
	}
	return 1;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> s >> t;
	for (int i = (int)s.size() - 1; i >= 0; i--) {
		for (int j = 0; j < 26; j++) cnt[i][j] = cnt[i + 1][j];
		cnt[i][s[i] - 'a']++;
	}
	for (int i = (int)s.size() - 1; i >= 0; i--)
		for (int j = 0; j < 26; j++) idx[cnt[0][j] - cnt[i + 1][j]][j] = i;
	int l = 0, r = n * (int)s.size();
	while (l < r) {
		int mid = (l + r + 1) / 2;
		if (check(mid)) {
			l = mid;
		}
		else {
			r = mid - 1;
		}
	}
	cout << l;
	return 0;
}

G

题目

我们可以找到对于每一个 A i A_i Ai,它的上一个和它相同的值的位置和下一个和它相同的值的位置。通过正序和倒序便利数组,存储这个值上一个出现位置,每遇到一个值将其上一个和它相等的值的位置更新为我们储存的这个值的位置,在更新这个值的上一个出现位置为现在遍历到的位置。

这样就算出了对于每一个只出现一次的数的区间范围,拿样例解释:

1 2 1 4 3 3 3 2 2 4

如果以第三个元素:1 为只出现一次元素的话,区间可以这么取:

1 [2 {1] 4 3 3 3 2 2 4}

其中中括号是左端点的范围,大括号是右端点的取值范围。

这样就有 2 × 8 2\times 8 2×8 16 16 16 种情况。

但是就这样会有重复的区间,朴素去重就是 N 2 N^2 N2 的时间复杂度了,怎么办呢?

我们可以把一个区间表示成一个点: [ i , j ] [i,j] [i,j] 表示成 ( i , j ) (i,j) (i,j),如图 i , j i,j i,j 2 , 3 2,3 2,3

在这里插入图片描述

那么两个区间里的点的组合是不是就可以表示成一个矩形?

那么样例中例子的矩形就是:

( 2 , 3 ) to ( 3 , 10 ) (2,3) \text{to} (3,10) (2,3)to(3,10)

这个矩形的面积就是这个值只有一个的区间的总和。

那么把这些矩形的面积并起来,求这个不规则图形的总面积就是我们要求的答案?

你应该可以想到 扫描线。

时间复杂度

O ( N log ⁡ ( N ) ) O(N\log(N)) O(Nlog(N))

什么?你不会?我放的链接是拿来干嘛的?

AC Code:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n, a[200100];
int l[200100], r[200100], l1[200100], r1[200100];
struct node{
	int l, r, tag;
	long long sum;
};
node t[1600100];
void maketree(int l, int r, int p) {
	t[p].l = l;
	t[p].r = r;
	if (l < r) {
		maketree(l, (l + r) / 2, p * 2);
		maketree((l + r) / 2 + 1, r, p * 2 + 1);
	}
}
void add(int l, int r, int p, int k) {
	if (t[p].l > r || t[p].r < l) return;
	if (l <= t[p].l && t[p].r <= r) {
		t[p].tag += k;
		if (t[p].tag) t[p].sum = t[p].r - t[p].l + 1;
		else t[p].sum = t[p * 2].sum + t[p * 2 + 1].sum;
		return;
	}
	add(l, r, p * 2, k);
	add(l, r, p * 2 + 1, k);
	if (!t[p].tag) t[p].sum = t[p * 2].sum + t[p * 2 + 1].sum;
}
struct segment{
	int l, r, x, f;
};
segment seg[1600100];
int segcnt;
bool cmp(segment a, segment b) {
	if (a.x == b.x) return a.f < b.f;
	return a.x < b.x;
}
long long ans;
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	for (int i = 1; i <= n; i++) {
		l[i] = r1[a[i]];
		r1[a[i]] = i;
	}
	memset(l1, 0x3f, sizeof(l1));
	for (int i = n; i >= 1; i--) {
		r[i] = l1[a[i]];
		l1[a[i]] = i;
	}
	for (int i = 1; i <= n; i++) r[i] = min(r[i], n + 1);
	for (int i = 1; i <= n; i++) {
		segcnt++;
		seg[segcnt].l = i;
		seg[segcnt].r = r[i] - 1;
		seg[segcnt].x = l[i];
		seg[segcnt].f = 1;
		segcnt++;
		seg[segcnt].l = i;
		seg[segcnt].r = r[i] - 1;
		seg[segcnt].x = i;
		seg[segcnt].f = -1;
	}
	maketree(1, n, 1);
	sort(seg + 1, seg + segcnt + 1, cmp);
	for (int i = 1; i < segcnt; i++) {
		add(seg[i].l, seg[i].r, 1, seg[i].f);
		ans += (long long)(seg[i + 1].x - seg[i].x) * (long long)t[1].sum;
	}
	cout << ans;
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/486007.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于四篇GNN论文的阅读笔记PPT:包括GATNE,AM-GCN,HGSL和coGSL

关于四篇GNN论文的阅读笔记PPT&#xff1a;包括GATNE&#xff0c;AM-GCN&#xff0c;HGSL和coGSL 前言GATNEAM-GCNHGSLcoGSL 前言 这里的PPT主要是在跟Graph Transformer一起的&#xff1a; 【图-注意力笔记&#xff0c;篇章1】Graph Transformer&#xff1a;包括Graph Trans…

LeetCode每日一题——移除链表元素

移除链表元素OJ链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; 这与之前的移除元素的题目很相似&#xff0c;那么我们同样可以用类似的做法&#xff08;双指针&#xff09;进行解题。但是这是一个链表删除&a…

Less-1(sqlmap手工注入攻击)--sqli

第一步&#xff1a;判断他是什么sql注入&#xff1f; 1 报错 1 and 12 -- 错误结果(--表示注释符) 1 and 11 -- 正确结果 第二步&#xff1a;判断返回字段数 ?id1 order by 3-- 正确显示结果 ?id1 order by 4--当列数为4时开始报错&#xff0c;所以只有三列 注&#xf…

基于ssm的大学生心理健康的设计与实现

1 用户功能分析 1、注册、登录系统 2、心理预约指导&#xff1a;用户登录系统可以查看心理专家&#xff0c;可以预约时间进行指导。 3、在线交流&#xff1a;可以与其他用户进行交流互动 4、个人信息&#xff1a;可以修改个人信息&#xff0c;维护自己的信息 5、心理测试&…

目标检测中的mAP计算原理和源码实现

简介 在目标检测任务中&#xff0c;mAP&#xff08;mean Average Precision&#xff0c;平均精度均值&#xff09;是一个非常重要的评价指标&#xff0c;用于衡量模型在多个类别上的平均性能。它综合考虑了模型在不同召回率下的精确率&#xff0c;能够全面反映模型在检测任务中…

VMware 调整产品方案,该跟随还是撤退?全面评估不同用户应对策略

本文针对 VMware 调整后的产品组合进行深入分析&#xff0c;并根据不同用户使用情况给出详细的应对策略&#xff0c;干货满满&#xff0c;建议收藏阅读&#xff01;重点内容包括&#xff1a; VMware 产品变化梳理不同用户如何选择应对策略&#xff1a;评估角度与应对思路梳理延…

ChatGPT 对 ELT的理解

本文主要内容来自 ChatGPT 4.0 到底什么是 ETL&#xff1f;在数据库内部&#xff0c;把数据从 ODS 层加工成 DWD&#xff0c;再加工成 DWS&#xff0c;这个过程和 ETL 的关系是什么&#xff1f;带着这些问题&#xff0c;我问了一下 ChatGPT&#xff0c;总结如下。 数据在两个数…

下载最新VMware,社区版本(免费)

VMware - Delivering a Digital Foundation For BusinessesRun any app on any cloud on any device with a digital foundation built on VMware solutions for modern apps, multi-cloud, digital workspace, security & networking.https://www.vmware.com/ 官网地址

【SpringBoot】了解简单原理 Bean管理 配置优先级

文章目录 一、配置优先级1.1 命令行设置端口号1.2 打包后修改端口号1.3 优先级 小结 二、Bean的管理2.1 获取Bean2.2 Bean作用域2.3 第三方Bean 三、剖析Springboot的底层原理3.1 起步依赖3.2 自动配置3.2.1 第三方类装配3.2.2 原理分析 总结Web后端开发总结&#xff1a;源码跟…

笔记本电脑与服务器首选:PW1605可编程电流限制开关,稳定可靠新标准

一般描述 PW1605 是一款电流限制开关&#xff0c;具有可编程输入过压保护和输出电压箝位功能。集成保护 N 沟道 FET 具有极低的 RDS&#xff08;ON&#xff09; 功能&#xff0c;PW1605有助于降低正常工作期间的功率损耗。可编程软启动时间控制启动期间输出电压的压摆率。独立的…

python实现常见统计量与统计分布

一. 基本概念 1. 总体 一个统计问题研究对象的全体称为总体&#xff0c;构成总体的每个成员称为个体。 2. 样本 一般由于总体的数量是非常巨大的&#xff0c;不可能对全部总体进行研究&#xff0c;通常会对总体进行抽样进行研究。 从总体中按一定规则抽出的一部分个体称为…

UE4_官方动画内容示例1.2_动画蓝图——使用蓝图告知Actor播放动画

展示了两个示例&#xff1a;在其中一个示例中&#xff0c;使用蓝图告知Actor播放动画&#xff0c;在另外一个示例中&#xff0c;展示了告知Actor播放动画的动画蓝图&#xff08;例如&#xff0c;此示例展示了如何将变量从蓝图传递给动画蓝图&#xff0c;并演示了如何将现有姿势…

.NET高级面试指南专题二十三【 B+ 树作为索引有什么优势】

B 树作为索引有许多优势&#xff0c;这些优势使其成为许多数据库管理系统中首选的索引结构之一。以下是 B 树作为索引的一些主要优势&#xff1a; 高效的查询性能&#xff1a;B 树是一种平衡树结构&#xff0c;具有良好的平衡性和高度平衡的性质&#xff0c;这使得在 B 树上进行…

leetcode刷题日记-滑铁卢了家人们(解数独)

问题描述 解题思路 看到这个题&#xff0c;给我的感觉是什么玩意啊&#xff01;仔细读题之后&#xff0c;真的没想到解题思路。然后看了题解&#xff0c;用到了回溯算法&#xff0c;感觉这个回溯和N皇后的问题差不太多。然后就照着思路尝试理解了一遍&#xff0c;感觉这种题目…

电脑怎么解除安全模式?

安全模式是windows系统中的一种特殊模式,在安全模式可以让系统仅载入最低需求的驱动程序来启动电脑,用户可以在此模式下检测或故障排除。可是一些用户却不知道怎么解除安全模式。下面,极客狗就为大家带来电脑怎么解除安全模式的方法吧。 解除安全模式的方法: 1、 首先,在安…

Python使用flask框架与前端建立websocket链接,并进行数据交互

Python使用flask框架与前端建立websocket链接,并进行数据交互 后端采用的框架为flask,前端用的flask自带的html编写,实现的功能为:前后端建立websocket链接并进行数据交互 一、编写一个flask后端服务 常规创建方式就可以,创建一个flask服务。声明一个websocket实例,以we…

详解mysql安装与配置,及Mac中常见的安装问题

目录 1 数据库介绍 什么是数据库 数据库分类 2 MySQL服务器安装 2.1 Windows绿色安装 2.2 Windows中重装MySQL 3 Mac中常见的安装问题 4 客户端连接MySQL服务器 5 SQL分类 1 数据库介绍 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 文件…

文件上传一-WEB攻防-PHP应用文件上传函数缺陷条件竞争二次渲染黑白名单JS绕过9

演示案例&#xff1a; PHP-原生态-文件上传-前后端验证PHP-原生态-文件上传-类型文件头验证PHP-原生态-文件上传-后缀黑白名单验证PHP-原生态-文件上传-解析配置&二次渲染PHP-原生态-文件上传-逻辑缺陷&函数缺陷 #学习前必读&#xff1a; 1、课前一定要明白&#xff1a…

【教程】高效数据加密混淆方法及实现简介

背景 在需要对数据进行传输或者表达时&#xff0c;通常要求数据加密的安全级别不高&#xff0c;但希望加解密时间复杂度尽可能低。这时使用传统的对称加密&#xff08;如3DES、AES&#xff09;或非对称加密&#xff08;如RSA、ECC&#xff09;显然不太适合。因为加密的安全级别…

PSO-CNN-BiLSTM多输入时序预测|粒子群优化算法-卷积-双向长短期神经网络时序预测|Matlab

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&am…