后面与蓝桥杯用到的算法相关
头文件
iostream
iostream.h是input output stream的简写,意思为标准的输入输出流头文件。它包含:
(1)cin>>"要输入的内容"
(2)cout<<"要输出的内容"
这两个输入输出的方法需要#include<iostream>头文件来声明。
Return 0;
1.
sprintf(s, "%d", 123); //把整数123打印成一个字符串保存在s中
{
int a;
char arr1[5]="9657"
sscanf(arr1,"%d",&a);//从arr1字符数组中读取一个整数
2.高精度计算
高精度计算的基本方法
用字符串来读入数据
将字符串转为整数数组,该数组的每一个元素对应一位十进制数,下标顺序指明每一位的序号(为了计算对位的方便,一般会进行倒序存储),一般还用其下标0来存储该数的位数,如a[0],也是为了方便计算和输出等。
然后对每一位进行计算,运算规则如同算术运算。
输出的时候一般也是倒序(因为存储的时候是倒序的)。
3.三目运算符
max=(a>b)?a:b; 执行该语句的语义是:如a>b为真,则把a赋予max,否则把b 赋予max。
4.putchar函数只能输出字符数据,而puts函数可输出字符串数据。 puts (s)的作用与语句printf ("%s”,s)的作用基本相同,puts ()函数只能输出 字符串 ,不能输出数值或进行格式变换。
Eg:putchar((a[i] - 'a' + n) % 26 + 'a');//
5.指针遍历二维数组
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)
6. i++和++i
所以说两者参与运算时的区别就是:
- a=i++ , a 返回原来的值a=i,i=i+1;
a=++i , a 返回加1后的值,a=i+1,i=i+1。
也就是i++是先赋值,然后再自增;++i是先自增,后赋值。 - 第二个区别就是: i++ 不能作为左值,而++i可以。
7. if(k&1) //如果k是奇数
8.长整数是在数据较大的时候使用,即超过32767的时候使用。
9.Special Judge是指本题可能有多个正确的解。你的程序的答案将被一个SPJ的检测程序检测,以判断你的程序是否正确。请注意:SPJ的题目一般不会判出PE,所以请确保你的程序输出格式正确。
10.
所有循环都能改成递归。{找循环,设参数,找出口}
11.Static 静态全局变量
12. memset
函数的功能是:将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,注意 c 是 int 型。s 是 void* 型的指针变量,所以它可以为任何类型的数据进行初始化。
memset() 的作用是在一段内存块中填充某个给定的值。因为它只能填充一个值,所以该函数的初始化为原始初始化,无法将变量初始化为程序中需要的数据。用memset初始化完后,后面程序中再向该内存空间中存放需要的数据。
memset 一般使用“0”初始化内存单元,而且通常是给数组或结构体进行初始化。一般的变量如 char、int、float、double 等类型的变量直接初始化即可,没有必要用 memset。如果用 memset 的话反而显得麻烦。
13. fabs浮点数的绝对值
14.1e-8 极小数,迭代停止
15.EOF
(while(scanf("%d",&n) != EOF))
加上" != EOF"后该程序就不是死循环了,如果在终端不进行输入该程序会自动结束
要注意的是:在终端(黑框)中手动输入时,系统并不知道什么时候到达了所谓的“文件末尾”,因此需要用<Ctrl + z>组合键然后按 Enter 键的方式来告诉系统已经到了EOF,这样系统才会结束while.
16. bfs首先找到的目标便一定是用时或步数最少的,
DFS的树的深度如果过长的话考虑用B F S BFSBFS而不去用D F S DFSDFS
17. %.0f 是输出 float 型或 double 型数据,按定点格式,小数点以下占0位。
也就是输出浮点数的整数部分,不输出小数点和小数点以下部分。小数部分 4 舍 5 入。
18. 为什么是 0x3f
?
如果两点之间距离不相等,就不能用BFS了,需要用Dijkstra等通用算法。
写 dijkstra
等等经典算法时;我们希望 dist
数组初始值是 无穷大
的数,常常会用到 memset(dist, 0x3f, sizeof dist)
。为什么要给 dist
赋值为 0x3f3f3f3f
呢?
如果是负值 int mini=-0x3f3f3f3f;//一个常用的极小值
19.
不适用于带负权重问题,但在无负权重问题中效率为最高
20
动态规划算法的核心就是记住已经解决过的子问题的解。
21.动态规划
关键:
确定状态(最后一步,子问题),转移方程,初始条件(用转移方程算不出来,又需要手动定义)和边界情况
21.动态数组
在创建动态数组的过程中我们要遵循一个原则,那就是在创建的时候从外层往里层,逐层创建;而释放的时候从里层往外层,逐层释放。
22.全排列
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
23 dfs 可回溯
标记点,确定范围,递归
24.n&(1<<i)的含义
1<<i 是将1左移i位,即第i位为1,其余位为0;
例如1<<2 则0001->0100
n&(1<<i)是将左移i位的1与n进行按位与,即为保留n的第i位,其余位置零
如果n第i位为0,则n&(1<<i)的值为0
否则不为0
常用if(n&(1<<i)==0)用于判断n的第i位是否为0
(i&1) 是按位 与 运算,相当于 取出 i 的2 进制数值的个位数。 如果 i 是 十进制 奇数,i&1 得 1; 如果 i 是 十进制 偶数,i&1 得 0。
25.链表
、
26.C语言局域变量优先,可修改全局变量
27.quene
28. hash散列表的缺陷
散列表并不是适用于所有的需求场景,那么哪些情况下不适合使用呢?
- 散列技术一般不适合在允许多个记录有同样关键码的情况下使用。
因为这种情况下,通常会有冲突存在,将会降低查找效率,体现不出散列表查找效率高的优点。
并且如果一定要在这个情况下使用的话,还需要想办法消除冲突,这将花费大量时间,那么就失去了 O(1) 时间复杂度的优势,所以在存在大量的冲突情况下,我们就要弃用散列表。
- 散列方法也不适用于范围查找,比如以下两个情况。
- 查找最大值或者最小值
因为散列表的值是类似函数的,映射函数一个变量只能对应一个值,不知道其他值,也不能查找最大值、最小值,RMQ(区间最值问题)可以采用 ST 算法、树状数组和线段树解决。
- 也不可能找到在某一范围内的记录
比如查找小于 N 的数有多少个,是不能实现的,原因也是映射函数一个变量只能对应一个值,不知道其他值。
方法:除留余数法、直接定址法、数字分析法。
29. freopen(“maze.txt”,”r”,stdin); ///从文件中读入
30.剪枝
不用全部遍历,可以和之前的比较。
31
Char c
A[i]=c-‘0’
32.
int 最多表达 2^31 - 1,10位整数;
long long 最多表达 2^63 - 1,19位整数
33.差分(整体做+-)
差分算法解题的基本思路:
- b[1]=a[1];
- 从第 2 项到 n 项,利用 b[i]=a[i]-a[i-1]b[i]=a[i]−a[i−1] 差分式;
- 对于区间端点操作加减;
- 差分还原(前缀和)。
- 注意是从1开始,从0开始还有讨论i=0 的情况,使用1的话 b[1]=a[1]-a[0]=a[1]-0;
while (m--) {
加减值
B[l]+=value
B[r+1]-=value;
Sum=0
For(i=1
Sum=sum+b[i]
34. 前缀和的特点:
- 将对于区间的求和操作转化为对于端点值的减法的操作;
- 区间求和操作的时间复杂度为 O(1);
- 数组存放时要从 1 开始;
- 前缀和数组比原来的数组序列多一个数,第 0 个
35.abs绝对值
fabs
功 能: 返回浮点数的绝对值
用 法: double fabs(double x);
Sort()默认升序
lower_bound(int* first,int* last,val)
;
作用:查找有序区间[first,last]中第一个大于等于x的位置
最大公约数gcd(x,y)
//公倍数 两数相乘 除以公约数
36.闰年
If((year%4==0&&u%100!=0)||(year%400==0)
多测试几组样例
37.<sstream>
Stringstream si;
Si<<a[i]<<”/”<<a[i+1
38 .
! > 算术运算符 > 关系运算符 > && > || > 赋值运算符
39.