c++代码实现中时间复杂度的不断优化

c++代码实现中时间复杂度的不断优化

先来介绍一下时间复杂度:

同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率。算法分析的目的在于选择合适算法和改进算法。

计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。这是一个关于代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,它考察当输入值大小趋近无穷时的情况。


 

时间复杂度的优化通常在暴力枚举中尤为重要,或许O(n*n)会得零分但是O(n*logn)可以得满分,所以在编写程序过程中我们要优先考虑时间较短的算法(洛谷里最绝望的就是看到TLE,这意味着代码要重新编写)。总之有快方法用上绝对没问题,除非NOIP时间不够可以快速写一段骗(拿)一些分数。



 

下面以洛谷P2241 统计方形(数据加强版)为例讲解一下具体如何不断优化程序的时间复杂度:

例10.1 (洛谷 P2241, NOIP1997 普及组 加强)

有一个 n×m(n, m ≤ 5000) 的棋盘,求其方格包含多少个(四边平 行于坐标轴的)正方形和长方形。

本题中, 长方形中不包括正方形。

样例解释: 如图,正方形一共 8 个,长方形 10 个 正方形中,边长为 1 的 6 个,边长为 2 的 2 个;

     长方形中, 1 ×2 的 4 个, 1 ×3 的 2 个, 2 × 1 的 3 个, 2 ×3 的 1个。


 

思路1:用四重循环,直接枚举 4 个参数,即两横边两竖边:

通过左上角和右下角的顶点进行枚举,如果长度相等就是正方形,否则就是长方形。

所以,这样可以保证不重复地遍历所有的方形。

根据循环的范围可知,我们也没有遗漏任何的方形。

时间复杂度O(n2 m2 ) ……似乎有点慢。

但是至少, 答案正确了。

 1 //枚举左上、右下顶点 时间复杂度O(n^2*m^2) 
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 typedef long long LL; //LL是已经定义好的long long
 5 int main(){
 6     int n,m;
 7     LL squ=0,rec=0;//squ统计正方形个数,rec统计长方形个数 
 8     cin>>n>>m;
 9     for(int x1=0;x1<n;x1++)
10     for(int y1=0;y1<m;y1++)
11     for(int x2=x1+1;x2<=n;x2++)
12     for(int y2=y1+1;y2<=m;y2++)    //四层循环不TLE才怪    
13         if (x2-x1 == y2-y1)squ++;
14         else rec++;
15     cout<<squ<<" "<<rec<<endl;
16     return 0;
17 }
hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » c++代码实现中时间复杂度的不断优化