算法总结
文章平均质量分 71
SeasonJoe
这个作者很懒,什么都没留下…
展开
-
N皇后问题与回溯法
八皇后问题,快三个月了,原来不会写现在还是不会,感觉递归还是不理解,每次看别人的代码都要想一下,更不讲自己写了这里明显用到了回溯法,这种递归我看看是没问题的,可以说比较简单,但自己写就难了回溯法要注意一个问题就是:如果在回溯法中用了辅助的全局变量,则一定要把它们恢复原状,特别的,如果函数有多个出口,每个出口都要及时恢复被修改的值这也是比较好理解的,如果递归不成功返回的时候原本的值要恢复原创 2015-12-17 22:42:52 · 2191 阅读 · 0 评论 -
RMQ问题
BMQ问题就是在一系列连续的数中,找出一个区间内最小的数,基本思路就是用d[i][j]表示从i开始,长度为2^j的一段元素中的最小值,直接先递推预处理,时间是O(nlogn),查找就O(1)基本模板:#include#include#includeusing namespace std;const int maxn = 10000;int d[maxn][maxn];void原创 2016-11-14 15:46:09 · 411 阅读 · 0 评论 -
大数的加减乘除
最基本的一个运算,可以用数组或指针做 1.加法 一:数组1.自己的代码,真是一点都不简洁,水平有限啊!#include#includeint max(int len1, int len2){ return len1 > len2 ? len1 : len2;}int main(){ char s1[100], s2[100],s3[100]; in原创 2015-11-29 15:12:47 · 474 阅读 · 0 评论 -
堆排序的实现
暑假开始啃算法导论了,先解决堆的问题。首先堆排序使用的是最大堆,特点是堆顶元素大于其他所有数,堆排序就是利用了这一点,需要三个函数:1.维护最大堆性质:MaxHeapify(int a[], int i),基本思路是比较节点i和它的左右孩子,选出最大的交换位置,注意交换后可能导致它的子数不符合最大堆原则,所以要递归再求一遍,它的复杂度为O(lgn)2.建堆:BuildMaxHeap(i原创 2016-07-16 22:43:36 · 284 阅读 · 0 评论 -
非递归实现二叉树的各种遍历
逛知乎看到有人去微软面试遇到让白板写非递归的二叉树的中序遍历,自己想了一下,非递归基本上就是用栈模拟,其他还好,后序遍历比较难写。参考博客:点击打开链接#include#include#includeusing namespace std;typedef struct treenode{ char data; treenode *left,*right;}treen原创 2016-06-29 16:37:13 · 410 阅读 · 0 评论 -
欧几里德与拓展欧几里德算法
做poj1061的时候接触到了拓展欧几里德算法,所以查阅了一下白书和网上的解释,现在整理一下。欧几里德算法:欧几里德算法比较简单,就是俗称辗转相除法的一直求两个数的最大公约数的算法,关键在于:gcd(a,b)=gcd(b,a mod b),与边界条件gcd(a,0)=a结合就可以递归求得结果。核心代码:int gcd(int a, int b){ return b == 0 ?原创 2016-04-18 14:07:36 · 392 阅读 · 0 评论 -
线性筛法求素数
求素数是比较基本的内容,有时候我们会需要打一个素数表。一般如果n比较小我们会使用(%2~sqrtn)这种算法,简单但是时间耗费很多,复杂度是O(n^2)。这里介绍一种筛选求素数法,基本要点是,如果找到一个素数如3,那么就往后筛出所有3的倍数。一般筛选求素数:void init(){ memset(prim, true, sizeof(notprim)); for (int i = 2原创 2016-04-07 08:10:05 · 670 阅读 · 0 评论 -
贪心法经典问题总结
乘船问题:要点什么的看白书,解释的已经很详细了。从这道题我们可以证明贪心法不会丢失最优解,因此可以通过贪心得到最优解。题目:点击打开链接#include#include#include#includeusing namespace std;int main(){ int t,w,n,i,j; int a[305]; scanf("%d", &t); whi原创 2016-04-06 16:27:03 · 1030 阅读 · 0 评论 -
子集生成
一:增量构造法思路是一次选出一个元素放入集合中#includevoid print_subset(int n,int a[],int cur){ for (int i = 0; i < cur; i++) printf("%d ", a[i]); printf("\n"); int s = cur? a[cur - 1] + 1 : 0;//cur为0则s为0,否则s=a[原创 2016-03-09 19:05:18 · 376 阅读 · 0 评论 -
枚举排列
根据字典序,依次输出全排列,整理一下,有两种方法:一种递归,一种利用C++中的STL一:生成可重集的排列#include#include#includeint p[20];int cmp(const void *a, const void *b){ return *(int *)a - *(int *)b;}void print_permutation(int n, i原创 2016-03-06 16:20:09 · 415 阅读 · 0 评论 -
快速排序(二维数组)
会用qsort函数,但一直搞不清cmp返回值的作用,而且不会二维数组的排序,做poj1609的时候因为二维数组的快排WA了一个晚上,实在郁闷。下定决心彻底搞懂它,以后一点点的补充。qsort函数是编译器函数库自带的快速排序函数,头文件是stdlib.h 用 法:qsort(void base,int nelem,int width,int (*fcmp)(const void ,const voi原创 2015-11-26 22:30:43 · 6374 阅读 · 1 评论 -
树状数组基本概念
做POJ有关逆序对的题时得知了有树状数组这一大杀器,赶快学习了一下 树状数组如图: 由上图可以看出树状数组跟二分很相似,将一个数组转换成了一个树(话说怎么想到的?这算法实在膜拜),因此将复杂度降低到了nlogn。 C[n]可以由前面的C数组之和来求出,那么是怎么算的呢?这里的计算都是以二进制为基础。首先是有一个lowbit函数,lowbit(k)就是把k的二进制的高位1全部清空,只留下最低原创 2015-12-03 21:56:16 · 349 阅读 · 0 评论 -
树状数组求逆序对
求逆序对最常用的方法就是树状数组了,确实,树状数组是非常优秀的一种算法。在做POJ2299时,接触到了这个算法,理解起来还是有一定难度的,那么下面我就总结一下思路:首先:因为题目中a[i]可以到999,999,999之多,在运用树状数组操作的时候,用到的树状数组C[i]是建立在一个有点像位存储的数组的基础之上的,不是单纯的建立在输入数组之上。 比如输入一个9 1 0 5 4(最大9),那么C[i]原创 2015-12-06 11:46:03 · 7556 阅读 · 1 评论 -
C中qsort的补局限和C++中sort的用法
最近在做树状数组的逆序数,其实早就发现了qsort的局限性:即数组a[n]排序必须从0开始,如果从1开始到n,会出现某一项为0的情况。导致树状数组中lowbit完全没法求,无奈只能去学习了一下C++中sort函数#include<stdio.h>#include<algorithm> //这是sort的头文件using namespace std; //这个必须加bool cmp(int a,原创 2015-12-06 10:40:59 · 407 阅读 · 0 评论 -
有环图求环的个数和具体节点数
这个问题一直没仔细写过,cf上做到了就写一下,就是用栈存储+回溯,很简单。#include#include#include#include#includeusing namespace std;const int N = 20;vector edge[N];int s[N],top=0;//stl里的stack没办法遍历,所以用数组模拟bool instack[N];int原创 2016-12-07 19:35:31 · 5441 阅读 · 2 评论