算法学习
梵高先生敲代码
这个作者很懒,什么都没留下…
展开
-
基础算法学习——离散化(区间合并)
题目描述离散化思想离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。题解1)创建需要用到的数组和集合int N = 300010; //因为需要将所有x,l,r存在数组中,这样就是n + 2m <= 300000int[] a = new int[N]; //从1开始,需要通过x找到离散量,然后+1,int[] s = new int[N]; //前缀和来做,所以需要从1开始记录aLis原创 2020-10-05 11:34:41 · 473 阅读 · 0 评论 -
基础算法学习——双指针算法(最长连续不重复子序列)
题目描述双指针算法思想常见问题分类:(1) 对于一个序列,用两个指针维护一段区间(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作对于这道题来说,要求最长连续不重复子序列的长度,则应该用两个指针共同确定一个元素不重复区间题解1)定义数组a[N]和数组s[N],数组a用来存放键盘输入的整数序列,定义两个指针i和j来共同维护一段区间,数组s用来存放这段区间里元素出现的次数s[a[i]]++;2)i指针往数组末尾移动,s数组统计i指针指向的每个元素出现的次数,当碰到某个元原创 2020-09-28 13:01:41 · 260 阅读 · 0 评论 -
基础算法学习——二维差分
题目描述算法思想和一维差分一样 一维差分题解构造一个新的数组b[N][N]使原来的数组a[N][N]里面的每一个元素都是数组b里面元素的前缀和完整代码#include<stdio.h>#define N 1001void insert(int x1, int y1, int x2, int y2, int c);int a[N][N], b[N][N];int main(void){ int n,m,q,i,j; scanf("%d%d%d",&n,&原创 2020-09-27 13:35:19 · 337 阅读 · 0 评论 -
基础算法学习——一维差分
题目描述差分思想差分的思想是前缀和思想的逆运算,通过构造一个新的数组,使原来的数组的每一个元素是新数组的前缀和题解1)2)当要给a数组里l到r区间里的每个元素加上c时只需给b[l]加上c,就可以给a数组里l到N区间里每一个元素都加上c;然后我们可以把吧b[r+1]到b[N]间的每个数都减去一个c,即可只让l到r区间里的每个数都加上c b[l] += c; b[r+1] -= c;完整代码#include<stdio.h>#define N 100001void ins原创 2020-09-27 13:02:52 · 837 阅读 · 0 评论 -
基础算法学习——二维前缀和
题目描述二维前缀和思想和一维前缀和一样 一维前缀和题解1)构造一个二维数组s[N][N]使得二维数组里的每一个元素都是原来数组的前缀和s[i][j] = s[i][j-1]+s[i-1][j]-s[i-1][j-1]+a[i][j];2)要求子矩阵的和,则可以通过s[N][N]来求s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];完整代码#include<stdio.h>#define N 1001int a[N]原创 2020-09-27 12:36:00 · 1405 阅读 · 0 评论 -
基础算法学习——一维前缀和
题目描述前缀和思想构造一个新的数组,使得该数组里的每个元素都是原来数组的前缀和题解1)构造一个新的数组s[N],使得该数组里的每个元素都是原来数组的前缀和for(i=1; i<=n; i++) { scanf("%d",&a[i]); s[i]=s[i-1]+a[i]; }2)要求原来数组里下标从l到r的元素的和:a[l]+a[l+1]+…+a[r]则可以通过数组s[N]来求:s[l-1]=a[1]+a[2]+…+a[原创 2020-09-27 11:53:24 · 469 阅读 · 1 评论 -
基础算法学习——整数二分
题目描述二分法思想前提:数据是有序的比较这组数据中间的那个数与要查找的数的大小,根据比较结果缩小比较区间,当比较区间为1时即锁定我们要查找的数题解第一步:确定要查找的数(该数在数组中可能有多个)是左边界(第一个x)还是右边界(第二个x)第二步:选对应的二分模板1)查找左边界比较区间的中间值与x的大小,若中间值大于等于x则将r=mid区间缩小一半,否则l=mid+1,循环上面步骤,直到l=r。此时区间长度为1,覆盖的那唯一一个数就是我们要查找的x。对应模板:while(l<r)原创 2020-09-18 11:41:40 · 315 阅读 · 0 评论 -
基础算法学习——归并排序
题目描述归并排序思想1)归并排序也是基于“分治”的思想实现的,但和快速排序不一样的是,归并排序需要将需要排序的数存入一个数组,并取这个数组元素下标的中点作为分解点(分界点为下标),而快速排序是取任何一个数组元素作为分界点2)归并排序需要递归地分别先给分界点左右两边的数归并排序,等左右两边的顺序均排好后,再把左右两边整体归并排序题解第一步:将所要排序的数存入一个数组q(数组下标从l到r)第二步:选取数组中间的那个下标作为分界点第三步:将数组从中间点分为两部分,分别用i和j指向这两部分开头元素原创 2020-09-17 10:23:30 · 124 阅读 · 0 评论 -
基础算法学习——快速排序
题目描述快速排序思想快排是基于“分治”来做的1)首先在要排序的一串数里找出一个数x作为分界点,使该数左边的数都小于等于x,右边的数都大于等于x。2)然后采用同样的方法递归,给左右两边分别排序。题解第一步:将要排序的数存到一个数组下标为从l到r的数组q[]里for ( i = 0; i < n; i++) { scanf("%d ",&q[i]); }第二步:选取一个分界点x,在这里我直接选中间的那个数作为分界点x = q[(l+r)/2]//注意:选取分界点时原创 2020-09-16 15:21:18 · 163 阅读 · 1 评论