在如今的比赛,能否写出题已经是一个大问题了,就算暴力写出来也全是超时,时间复杂度如何压缩?这是小编自从写并查集以后开始重视的问题,如果在相同的水平下,而你却写法不同,说不定能拿更高的分数且只高不减,何乐而不为呢?让小编来为大家梳理几种常规压缩时间复杂度的方法。
Number 1 学习更多的算法
无论如何,学会更多的算法(如快速幂什么的),才能更好地优化你的程序,这才是最重要的方法,如果你只会模拟算法(即写暴力)是不行的,优化程序在于平时的积累,以下的捷径不会一定带来显著的效果。
Number 2 少用除法
小编多方打探,发现除法似乎在计算机中的运算极为复杂,会影响程序的速度,所以要多用到转化的方法,例如:代码if(a<b/2)这句判断语句用到了除法,那么怎么转换呢?可以改成if(a*2<b)也是可以的,这样一来,不紧保持了意思不变,还加快了速度,因此要多使用转化的方法。
Number 3 位运算
有时候还真的得使用除法,但是有时候除法也是可以优化的,此时就要使用位运算,举个栗子:现学两招,<<左移符号,在二进制分解中表示向左移一位,也就是a<<b,表示a*=2^b;>>则相反,a>>b,表示a/=a^b;有时使用位运算只是改变了一些写法,意思没变,却提高了效率,可以放心使用位运算。
Number 4 内联
内联函数这个名字听起来很麻烦的样子,其实想让一个普通函数成为内联函数很简单,只要在函数声明前加inline六个字母即可,众所周知,函数调用时会占用一定的时间,可是如果不写成函数,又会显得代码杂乱无章,既想写得好看,又想程序够快,不妨在函数前写上inline减去不必要的开销。但是内联函数还有一定的局限性,内联函数必须尽可能简单,否则编译器会自动强制取消内联,最好不要出现循环/递归。
Number 5 循环外定义VS循环内定义
代码一
代码二
对比以上两种代码,似乎意思相同,只不过是循环内定义和循环外定义。同样,代码一和代码二都用了n次赋初始值,但是代码一定义了x变量n次,而代码二则只用了1次,难道不是代码二更高效吗?所以提倡使用循环外定义。
Number 6 while(1)真的快吗?
虽然在竞赛中不常用while(1)这种死循环,但是平时我们会用到,小编一想到死循环,就会写while(1),但是事实证明写成for(;;)更快,小编猜想是因为while(1)的循环条件是1为真,需要不断判断,但是for(;;)的循环条件为空,就可以不判断,所以节约了时间。