进行的暑假训练的第一天,白天主要是按部就班的学习算法竞赛进阶那本书,主要学习了位运算和递归两方面的知识。
对于位运算,书上讲了很多关于原码,反码,补码的东西,因为上学期导论学过点皮毛,所以又看了一下。
位运算知识点总结及做题应用的技巧:
1. 位运算的优先级别(上网查资料)
2. 判断奇数还是偶数
使用&运算,与1进行&,如果为1,那么该数为奇数;如果为0,那么该数是偶数
3.左移:n<<1=2n 还有1<<n=2^n
右移:n>>1(向下取整) 区别于C++中n/2是向0取整,对于后面的二分法值域包含负数时不能正常工作
4.异或运算的特性:任意数和自身异或结果为0;0和任意数异或结果还是其本身。
不用临时变量交换两个数值
a ^= b
b ^= a
a ^= b
5.计算一个数值的二进制数中有多少个1
通过位运算,与1进行与运算,看是否结果为1,然后右移1位,继续判断。
6. 获得int型的最大值和最小值
int getMaxInt(){
return (1 << 31) - 1;//2147483647, 由于优先级的关系,括号不能省略
}
int getMinInt(){
return 1 << 31;//-2147483648
}
7. 计算2的n次方
2 << (n-1);//2的n次方
8.从低位到高位,取n的第m位
(n >> (m-1)) & 1;
9. 将一个数组中的数值初始化为正无穷时,常用memset(a,0x3f,sizeof(a))来表示
10. 如何快速求a的b次方对p取模
将位运算与递推结合可以降低时间复杂度。
对于递归,我只是掌握了最基本的数学的那几个问题,还从书上学到了关于 递归实现多项式,指数型,以及排列组合的枚举的一般遍历方式,还应该更加深入。
晚上做题总结:
b 题是一道dfs求连通块的问题,当时明白了题意,但是深搜的知识运用都差不多忘干净啦,所以今天在学习蓝皮书的同时,要抽空学习深搜广搜的知识。
a题我是最后大概看了一下题意,后来又重新看了一遍理解也正确,就是最少错几个步骤可以得到题目要求的值。
总结大概就是这些,希望以后每天都可以更加提高效率,在学蓝皮书的同时,也能把前晚做题遇到的不会的题目所涉及的算法知识点搞懂。