初赛一些知识

前缀,中缀,后缀(逆波兰)表达式

中缀表达式

中缀表达式是一个通用的算术或逻辑公式表示方法。其实中缀表达式跟我们平常见到的数学式子是一样的。

例如:1*(2+3)


前缀表达式
前缀表达式又称波兰表达式,,前缀表达式的运算符位于操作数之前

例如:- × + 3 4 5 6

前缀表达式求值
从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果

例如:- × + 3 4 5 6

  1. 从右至左扫描,将6、5、4、3压入堆栈
  2. 遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈
  3. 接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈
  4. 最后是-运算符,计算出35-6的值,即29,由此得出最终结果

中缀表达式转前缀表达式

方法:
我们设两个栈表,s1 s2.
从右到左遍历中缀表达式
如果遇到数字,将其压入s1中
如果遇到运算符时(s2):

  1. 若栈为空或栈顶的符号为’)’,直接压入s2中
  2. 若栈顶的运算符的优先级小于或等于当前符号,直接压入s2中
  3. 否则将s2中的栈顶运算符弹出,压入s1,再次转到(4-1)与s1中新的栈顶运算符相比较

遇到括号时

  1. 如果是右括号“)”,则直接压入s1
  2. 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃

重复步骤2至5,直到表达式的最左边
将s1中剩余的运算符依次弹出并压入s2
依次弹出s2中的元素并输出,结果即为中缀表达式对应的前缀表达式

在这里插入图片描述


后缀表达式
后缀表达式又称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后

例如:3 4 + 5 × 6 -

后缀表达式求值
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果

与前缀同理,这里就不做例子了

中缀表达式转后缀表达式

方法:
我们设两个栈表,s1 s2.
从左到右遍历中缀表达式
如果遇到数字,将其压入s1中
如果遇到运算符时(s2):

  1. 若栈为空或栈顶的符号为’(’,直接压入s2中
  2. 若栈顶的运算符的优先级小于或等于当前符号,直接压入s2中
  3. 否则将s2中的栈顶运算符弹出,压入s1,再次转到(4-1)与s1中新的栈顶运算符相比较

遇到括号时

  1. 如果是左括号“(”,则直接压入s1
  2. 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃

重复步骤2至5,直到表达式的最左边
将s1中剩余的运算符依次弹出并压入s2
依次弹出s2中的元素并输出,结果即为中缀表达式对应的后缀表达式(转换为后缀表达式时不用逆序)

在这里插入图片描述

NOIP竞赛的一些知识

竞赛推荐的竞赛语言有:
C++及C
free Pascal
Lazarus
Pascal
gcc/g++
Dev C++

不推荐的:
TP7(turbo pascal 7)
TC(turbo C)
Visual C++

编程规则:

  1. 对于每一道试题,选手只应提交一个源程序文件。源程序文件名由试题名称缩写加后缀构成,源程序文件名及后缀一律使用小写。PASCAL、C及C++程序的后缀分别为.pas,.c,或.cpp。当参赛选手对一道试题提交多份使用不同后缀的源程序文件时,测试系统按照.c, .cpp, .pas的顺序选取第一份存在的文件进行编译和评测,并忽略其他文件。
  2. 使用C/C++语言者不得使用自己的头文件,使用Pascal语言者不得使用自己的库单元。除另有规定外,每道题参赛程序源文件不得大于100KB,如选手在规定目录下另建其它子目录,这些子目录中的文件均会被评测系统忽略。
  3. 选手程序应正常结束并返回Linux系统,主函数的返回值必须为0。
  4. 选手程序中只允许通过对指定文件的读写、以及对指定库函数的调用等题目中明确规定的方式与外部环境通信。在程序中严禁下列操作:
  • 试图访问网络
  • 使用fork、exec、system或其它线程/进程生成函数
  • 打开或创建题目规定的输入/输出文件之外的其它文件和目录
  • 运行其它程序
  • 改变文件系统的访问权限
  • 读写文件系统的管理信息
  • 使用除读写规定的输入/输出文件之外的其它系统调用
  • 捕获和处理鼠标和键盘的输入消息
  • 读写计算机的输入/输出端口
  1. 除题目另有规定外,选手程序中所使用的静态和动态内存空间总和不得超过128MB

对C程序的限制
程序禁止使用内嵌汇编和以下划线开头的库函数或宏(自己定义的除外)。
在程序中只能使用下述头文件以及被它们所间接包含:assert.h, ctype.h, errno.h,float.h,limits.h,math.h,stdio.h,stdlib.h,string.h,time.h。
64位整数只能使用long long类型及unsigned long long类型。

对C++程序的限制
程序禁止使用内嵌汇编和以下划线开头的库函数或宏(自己定义的除外)。
64位整数只能使用long long类型及unsigned long long类型。
可以使用STL中的模板。
对Pascal程序的限制
程序禁止使用内嵌汇编,并禁止使用任何编译开关。
在程序中禁止使用除system库(自动加载)和math库(须用uses math子句)之外的其他单元。

凡满足上述规定,并且能在题目规定的命令行下编译通过的程序均为合法的源程序。但即使源程序合法,只要程序执行时有违规行为时,仍被判定为违规。

各种排序算法的总结

比较排序和非比较排序
常见的排序算法都是比较排序,非比较排序包括计数排序、桶排序和基数排序,非比较排序对数据有要求,因为数据本身包含了定位特征,所有才能不通过比较来确定元素的位置。
比较排序的时间复杂度通常为O( n 2 n^2 n2)或者O( n log ⁡ n n\log_n nlogn),比较排序的时间复杂度下界就是O( n / l o g n n/log_n n/logn),而非比较排序的时间复杂度可以达到O( n n n),但是都需要额外的空间开销。
比较排序时间复杂度为O( n log ⁡ n n\log_n nlogn)的证明:
a1,a2,a3……an序列的所有排序有 n ! n! n!种,所以满足要求的排序a1’,a2’,a3’……an’(其中a1’<=a2’<=a3’……<=an’)的概率为 1 / n ! 1/n! 1/n!。基于输入元素的比较排序,每一次比较的返回不是0就是1,这恰好可以作为决策树的一个决策将一个事件分成两个分支。比如冒泡排序时通过比较a1和a2两个数的大小可以把序列分成a1,a2……an与a2,a1……an(气泡a2上升一个身位)两种不同的结果,因此比较排序也可以构造决策树。根节点代表原始序列a1,a2,a3……an,所有叶子节点都是这个序列的重排(共有n!个,其中有一个就是我们排序的结果a1’,a2’,a3’……an’)。如果每次比较的结果都是等概率的话(恰好划分为概率空间相等的两个事件),那么二叉树就是高度平衡的,深度至少是 log ⁡ n ! \log_{n!} logn!
又因为 1. n! < nn ,两边取对数就得到log(n!)<nlog(n),所以 log ⁡ n ! \log_{n!} logn! = O( n log ⁡ n n\log_n nlogn).
2. n!=n(n-1)(n-2)(n-3)…1 > (n/2)^(n/2) 两边取对数得到 log ⁡ n ! \log_{n!} logn! > (n/2)$\log_{n/2}$ = Ω \Omega Ω( n log ⁡ n n\log_n nlogn),所以 log ⁡ n ! \log_{n!} logn! = Ω \Omega Ω( n log ⁡ n n\log_n nlogn)。
因此 log ⁡ n ! \log_{n!} logn!的增长速度与 n log ⁡ n n\log_n nlogn 相同,即 log(n!)= θ \theta θ(nlogn),这就是通用排序算法的最低时间复杂度O( n log ⁡ n n\log_n nlogn)的依据。

排序的稳定性和复杂度

  不稳定:

  选择排序(selection sort)— O(n^2)

  快速排序(quicksort)— O(nlogn) 平均时间, O(n^2) 最坏情况(要找的数在最左最右端); 
  对于大的、乱序串列一般认为是最快的已知排序

  堆排序 (heapsort)— O(nlogn)

  希尔排序 (shell sort)— O(nlogn)

  基数排序(radix sort)— O(n*k); 需要 O(n) 额外存储空间 (K为特征个数)



  稳定:

  插入排序(insertion sort)— O(n2)

  冒泡排序(bubble sort) — O(n2)

  归并排序 (merge sort)— O(n log n); 需要 O(n) 额外存储空间

  二叉树排序(Binary tree sort) — O(nlogn); 需要 O(n) 额外存储空间

  计数排序  (counting sort) — O(n+k); 需要 O(n+k) 额外存储空间,k为序列中Max-Min+1

  桶排序 (bucket sort)— O(n); 需要 O(k) 额外存储空间

怎么将一棵树转换为二叉树

解答:

  1. 将 当前点的孩子 放在左子树;
  2. 将 当前点的兄弟 放在右子树。

所以我们就可以得到江一棵树转换为二叉树后,根节点没有右子树
毕竟根节点没有兄弟!

拿一个例题来举例:
在这里插入图片描述
答案为:
在这里插入图片描述
就是这么简单

更新中…
LTH的初赛总结
WHDTXDY的初赛总结

猜你喜欢

转载自blog.csdn.net/bigwinner888/article/details/108670902
今日推荐