基础算法
文章平均质量分 55
对于基础算法的分类与总结
Brightess
湖南城市学院在读,大四学生
展开
-
倍增算法讲解 + 例题:AcWing 1273. 天才的记忆(RMQ问题的ST算法)
倍增,意思就是 “成倍增长”。在进行 递推 时,如果 状态空间很大,通常的 线性递推 无法满足 时间 与 空间复杂度 的要求,那么我们可以通过 成倍增长 的方式,只递推 状态空间 中在 2 的整数次幂位置上的值 作为代表。当需要 其他位置上 的值时,我们通过 “任意整数可以表示成若干个 2 的次幂项的和” 这一性质,使用 之前求出的代表值 拼成 所需的值。所以使用 倍增算法 的一个基本要求:递推问题 的状态空间 关于 2 的次幂 具有 可划分性。“倍增” 与 “二进制划分” 两个思想 互相结合,降低原创 2022-04-25 21:55:57 · 2472 阅读 · 0 评论 -
2022牛客寒假1 炸鸡块君与FIFA22(做法一:倍增 st表)
思路:这是一道关于 倍增(倍增算法讲解) 的一道典型例题。我们注意到 起始分数若在 % 3 意义下相等,则 经历 [l, r] 一段后分数的变化量是一个定值(重要)定义 st[3][200010][21] 之中 st[k][i][j] 表示 在初始分数为 k 的情况下 经历了 [i, i + 2 ^ j - 1] 一段游戏后 分数的 变化量;假设我们 已经预处理出了 st,则对于 每一次询问 ask,可以 先将某初始分数 start 对 3 取模,然后按照 倍增的套路 从 l 跳 若干个 2...原创 2022-04-26 12:20:37 · 720 阅读 · 0 评论 -
AcWing 1227. 分巧克力(二分答案求满足条件的最大值)
题意:给定n个长方形,每个长方形的长和宽分别是Hi、Wi,我们要从n个长方形中切出至少k个相同的正方形(满足正方形的边长为整数,且只能裁剪,不能拼凑)。思路:一、二分可行性证明及判断条件根据题目意思我们可以想到随着切出来的每个正方形巧克力边长越长,能得到的块数越少 ,体现在函数图像上就是一个单调递减的函数:对于给定的每一块巧克力,假设其长和宽分别是:hi、wi,如果我们想要切成边长是x的巧克力,那么可以切的块数应该为:(wi / x) * (hi / x) (x作为分母,这是个减函数,块数...原创 2022-03-10 21:45:40 · 208 阅读 · 0 评论 -
AcWing 1221. 四平方和(二分 or 哈希)
题意:给定一个整数n,我们要将这个整数分为四个非负整数的的平方和,输出字典序最小的一组解思路:数据范围是5e6,因此我们要将时间复杂度控制在O(n)以内或者O(nlogn)以内,本题可以考虑用二分来做,也可以用哈希来做。不过如果用哈希表做法的话则一定不能用STL中的哈希表,因为常数过大容易超时,应当手写哈希。二分的复杂度是O(nlogn),而手写哈希是O(n)的。两个算法的思想其实是一致的。先用二分来分析一下这道题。先考虑一下 a, b, c, d 四个数的范围,由于 N<=5e6,因..原创 2022-03-10 18:35:58 · 223 阅读 · 2 评论 -
AcWing 730. 机器人跳跃问题(典型二分答案求满足条件的最小值)
题意:机器人初始能量为E,下一个建筑高 H,如果当前能量大于H,那么跳到下一个建筑的能量变为 E + (E-H),否则能量为E-(H-E),其实两种情况可以归结为一种情况:2E - H,目标是到达第N个建筑,且 在这个过程中能量值不能为负数,问机器人初始能量E最少为多少?思路:对于 “最少/最大是多少” 这类问题,可以想一想是否能用二分来做那么如何确定是否能用二分呢?让我们回顾一下二分的具体步骤是什么:①判断是否具有二段性的性质,或者单调性(如果一个题目具有单调性那么一定可以用二分来做,如...原创 2022-03-10 12:31:43 · 386 阅读 · 0 评论 -
二分查找思想 + AcWing 789. 数的范围
二分查找的思想:①确定一个区间,使得我们要找的目标值一定在这个区间内出现②找一个性质,满足以下两点(整数二分和实数二分通用):(1)性质具有 二段性(100%一定成立)二段性含义:在一段区间中,前面一段连续的部分满足这个性质,后面一段连续的部分不满足这个性质,两部分无缝衔接,就如下图:(2)二分的答案 是 二段性的分界点。以整数二分为例子,有两种情况:“红色区间的右端点” 以及 “绿色区间的起点”,如下图:对于整数二分,二分答案有两种情况,对于不同的情况我们对应有着不同的做法。原创 2022-03-09 12:14:46 · 476 阅读 · 0 评论 -
CF Round 746 Div2:A. Gamer Hemose
谨以此篇 纪念一下我在CF通过的第一道题One day, Ahmed_Hossam went to Hemose and said “Let’s solve a gym contest!”. Hemose didn’t want to do that, as he was playing Valorant, so he came up with a problem and told it to Ahmed to distract him. Sadly, Ahmed can’t solve it… Coul原创 2021-10-05 22:32:20 · 213 阅读 · 0 评论 -
高精度系列汇总(大数加、减、乘、除)
AcWing 791. 高精度加法(高精度+高精度)给定两个正整数,计算它们的和。输入格式共两行,每行包含一个整数。输出格式共一行,包含所求的和。数据范围1≤整数长度≤100000输入样例:1223输出样例:35#include<iostream>#include<string>#include<vector>using namespace std;vector<int> add(vector<int>&原创 2021-08-21 10:45:07 · 144 阅读 · 0 评论 -
AcWing 26. 二进制中1的个数(按位与 or lowbit运算)
输入一个 32 位整数,输出该数二进制表示中 1 的个数。注意:负数在计算机中用其绝对值的补码来表示。样例1输入:9输出:2解释:9的二进制表示是1001,一共有2个1。样例2输入:-2输出:31解释:-2在计算机里会被表示成11111111111111111111111111111110,一共有31个1。按位与求某个二进制数x的第k位数:x>>k&1class Solution {public: int NumberOf1(int n) {原创 2021-08-20 10:43:05 · 113 阅读 · 0 评论 -
剑指Offer. 数字在排序数组中出现的次数(STL方法 or 库函数 or 整数二分)
统计一个数字在排序数组中出现的次数。例如输入排序数组 [1,2,3,3,3,3,4,5] 和数字 3,由于 3 在这个数组中出现了 4 次,因此输出 4。样例输入:[1, 2, 3, 3, 3, 3, 4, 5] , 3输出:4最近学习了c++中的STL容器和库函数,对于这两者的熟练掌握可以有效提高算法竞赛中用c++编写程序的效率。现在用两种容器:vector,multiset和库函数lower_bound和upper_bound做一下这道题。注意这道题使用了c++中的类编写,不可以直接在编原创 2021-08-19 16:35:37 · 137 阅读 · 0 评论 -
AcWing 790. 数的三次方根(浮点数二分,特殊值特判)
当n∈(-1,1)的时候,一定需要特殊判断,不然会出现错误答案(当n=0.001时)。原因:当n在这个区间的时候,n对应的答案(0.001的答案为0.1)并不在区间内,其三次方根答案比n还要大,因此[l,r]范围要扩大到[-1,1],区间中才会有答案。//浮点数二分模板题//当-1 < n < 1 特殊判断#include <iostream>#include<cstdio>using namespace std;bool check(double mid原创 2021-08-14 20:43:57 · 194 阅读 · 0 评论 -
AcWing 771. 字符串中最长的连续出现的字符(第一类双指针算法)
求一个字符串中最长的连续出现的字符,输出该字符及其出现次数,字符串中无空白字符(空格、回车和 tab),如果这样的字符不止一个,则输出第一个。输入格式第一行输入整数 N,表示测试数据的组数。每组数据占一行,包含一个不含空白字符的字符串,字符串长度不超过 200。输出格式共一行,输出最长的连续出现的字符及其出现次数,中间用空格隔开。输入样例:2aaaaabbbbbcccccccddddddddddabcdefghigk输出样例:d 10a 1#include<iostream&原创 2021-08-16 10:38:49 · 174 阅读 · 0 评论 -
归并排序模板分析(分治)
归并排序两大核心操作:一分为二,合二为一一分为二:将数组一分为二,一个无序的数组成为两个数组。合二为一:将两个有序数组合并成为一个有序数组。#include<iostream>#include<cstdio>using namespace std;const int N = 1e6+10;int m[N];int n;int tmp[N];void merge_sort(int m[],int l,int r){ if(l>=r) return;/原创 2021-08-14 15:34:17 · 93 阅读 · 0 评论 -
AcWing 778. 字符串最大跨距(正逆枚举匹配 or find()&rfind())
有三个字符串 S,S1,S2,其中,S 长度不超过 300,S1 和 S2 的长度不超过 10。现在,我们想要检测 S1 和 S2 是否同时在 S 中出现,且 S1 位于 S2 的左边,并在 S 中互不交叉(即,S1 的右边界点在 S2 的左边界点的左侧)。计算满足上述条件的最大跨距(即,最大间隔距离:最右边的 S2 的起始点与最左边的 S1 的终止点之间的字符数目)。如果没有满足条件的 S1,S2 存在,则输出 −1。例如,S= abcd123ab888efghij45ef67kl, S1= ab原创 2021-08-17 11:38:22 · 122 阅读 · 0 评论 -
快速排序模板(分治)
//快排模板#include <iostream>#include<algorithm>using namespace std;const int N = 1e6+10;int q[N];void quick_sort(int q[], int l, int r){ if (l >= r) return; int x = q[l + r >> 1], i = l - 1, j = r + 1;//①定分界点(分界点定为q[l]超时)原创 2021-08-14 10:18:10 · 79 阅读 · 0 评论 -
AcWing 766. 去掉多余空格(第一类双指针算法)
输入一个字符串,字符串中可能包含多个连续的空格,请将多余的空格去掉,只留下一个空格。输入格式共一行,包含一个字符串。输出格式输出去掉多余空格后的字符串,占一行。数据范围输入字符串的长度不超过 200。输入样例:Hello world.This is c language.输出样例:Hello world.This is c language.//简便做法:利用cin不接受空格,Tab,回车#include<iostream>#include<str原创 2021-08-15 21:01:45 · 232 阅读 · 0 评论 -
AcWing 789. 数的范围(整数二分查找左右边界)
给定一个按照升序排列的长度为 n 的整数数组,以及 q 个查询。对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。如果数组中不存在该元素,则返回 -1 -1。输入格式第一行包含整数 n 和 q,表示数组长度和询问个数。第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。接下来 q 行,每行包含一个整数 k,表示一个询问元素。输出格式共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。如果数组中不存在该元素,则返回 -1 -.原创 2021-08-14 19:15:41 · 137 阅读 · 0 评论