此博客原文地址:https://www.cnblogs.com/BobHuang/p/12654026.html
Bob老师遇到了3439: 完全平方数这个题目,他现在没啥想法。他选择去循环变量i从0到n看看是不是可以得到答案,于是写下了如下代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
//读入n
while (cin >> n)
{
//如果n为-1,结束循环
if (n == -1)
break;
//定义一个旗子,初始未插上。即n不是完全平方数
int flag = 0;
for (int i = 0; i <= n; i++)
{
//枚举的i等于n了结束循环
if (i * i == n)
{
//插上旗子,表示n是完全平方数
flag = 1;
break;
}
}
//分存在和不存在的情况
if (flag == 0)
cout << "No\n";
else
cout << "Yes\n";
}
return 0;
}
但是他悲伤得获得了TLE(Time Limit Exceeded),因为如果一个数不是完全平方数循环就要执行n+1次,如果是109那么就要执行09+1次,太慢了不能满足这个题目的要求。我们可以用大写字母O来表示时间复杂度,可以粗略的理解就是循环的次数,上述做法的算法复杂度是O(n),即线性阶(1和n比起来很小,被我们舍去了)。还有T组,那么总复杂度为O(T*n),接下来我们将优化这个做法。
一、做一些微小的优化
Alice和Bob说,你这也太傻了,有些循环完全不用运行,既然你知道i * i == n可以结束循环,那不是的时候什么时候可以循环呢。
如果是8,1 * 1 = 1 ;2 * 2 = 4;3 * 3 = 9。9已经比8大了,在找下去肯定也没有啊。Bob把下面的程序添了一个if,就通过了题目。现在我们的算法复杂度是O(T*sqrt(n)),也就是109的循环我只需要31624次,因为31623 * 31623 > 109。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
//读入n
while (cin >> n)
{
//如果n为-1,结束循环
if (n == -1)
break;
//定义一个旗子,初始未插上。即n不是完全平方数
int flag = 0;
for (int i = 0; i <= n; i++)
{
//枚举的i等于n了结束循环
if (i * i == n)
{
//插上旗子,表示n是完全平方数
flag = 1;
break;
}
//肯定不存在了,也要结束循环
if (i * i > n)
{
break;
}
}
//分存在和不存在的情况
if (flag == 0)
cout << "No\n";
else
cout << "Yes\n";
}
return 0;
}
哎呦,不错哦。如果让你求i*i<=n的i最大值呢,那我循环的时候统计ans不就好了。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
//读入n
while (cin >> n)
{
//如果n为-1,结束循环
if (n == -1)
break;
//定义答案,如果不存在为-1
int ans = -1;
for (int i = 0; i <= n; i++)