[学科竞赛]信息学奥赛基本算法.pptVIP

  • 24
  • 0
  • 约1.23万字
  • 约 97页
  • 2018-02-27 发布于浙江
  • 举报
[学科竞赛]信息学奥赛基本算法

第0讲:算法设计概论 时间复杂度 空间复杂度 调试方法与技巧 时间复杂度 O(1)常数阶 O(log N)对数阶 O(N)线性阶 O(N^2)平方阶 O(N^3)立方阶 …………………… 空间复杂度 O(1)常数阶 O(log N)对数阶 O(N)线性阶 O(N^2)平方阶 O(N^3)立方阶 …………………… 调试方法与技巧 Break Point Watch Table Data Check Code 问题分析 分析题目的模型 考虑要用的算法 分析算法的时空复杂度 如果符合要求即可 Coding 第一讲:递归 什么是递归? 递归就是指一个函数直接或者间接地调用自身。 问题的求解过程?划分成相同性质的子问题的求解,而小问题的求解过程可以很容易的求出,这些子问题的解就构成里原问题的解。 总体思想 待求解问题的解?输入变量x的函数f(x) 通过寻找函数g( ),使得f(x) = g(f(x-1)) 且已知f(0)的值,就可以通过f(0)和g( )求出f(x)值 推广 扩展到多个输入变量x,y,z等,x-1也可以推广到 x - x1,只要递归朝着“出口”的方向即可 递归的三个要点 递归式:如何划分子问题 递归边界:递归的终止条件,也就是最小的子问题 界函数:问题规模变化的函数,保证递归向边界靠拢 求n! #include iostream.h int F(int n) { if (n == 0) return 1; else return n * F(n - 1); } 栈 递归的实现是需要栈的,这里所使用的栈是系统自带的栈 栈是一种数据结构,它符合先入后出的原则 解决递归问题的关键 找出递推公式:即如何将问题划分为小规模的问题 找到边界条件 NOTICE:由于函数中的局部变量是存在系统的栈上的,如果你的局部变量过大,如较大的数组,将有可能栈溢出,这个时候要考虑全局变量和人工栈的使用。 汉诺塔问题 现在有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘,现在把所有盘子一个一个移动到柱子B上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方,请问至少需要多少次移动,并输出步骤。 汉诺塔问题  void hanoi(int n,char A,char B,char C)   {   if(n==1)   {   printf(Move disk %d from %c to %c\n,n,A,C);   }   else   {   hanoi(n-1,A,C,B);   printf(Move disk %d from %c to %c\n,n,A,C);   hanoi(n-1,B,A,C);   }   }    前序中序求后序 树中已知先序和中序求后序。 如先序为:abdc,中序为:bdac . 则程序可以求出后序为:dbca 。 前序中序求后序 算法思想:先序遍历树的规则为中左右,则说明第一个元素必为树的根节点,比如上例中的a就为根节点,由于中序遍历为:左中右,再根据根节点a,我们就可以知道,左子树包含元素为:db,右子树包含元素:c,再把后序进行分解为db和c(根被消去了),然后递归的进行左子树的求解(左子树的中序为:db,后序为:db),递归的进行右子树的求解(即右子树的中序为:c,后序为:c)。如此递归到没有左右子树为止。 前序中序求后序 void pronum(char pre[],int pre_s,int pre_e,char in[],int in_s,int in_e) { char c; int k; if(in_sin_e) return ; /* 非法子树,完成。 */ if(in_s==in_e){printf(%c,in[in_s]); /* 子树子仅为一个节点时直接输出并完成。 */ return ; } c=pre[pre_s]; /* c储存根节点。 */ k=find(c,in,in_s,in_e); /* 在中序中找出根节点的位置。 */ pronum(pre,pre_s+1,pre_s+k-in_s,in,in_s,k-1); /* 递归求解分割的左子树。 */ pronum(pre,pre_s+k-in_s+1,pre_e,in,k+1,in_e); /* 递归求解分割的右子树。 */ printf(%c,c); /

文档评论(0)

1亿VIP精品文档

相关文档