18次方,long long范围……
时限多少,1秒吗?
这真的是给刚学循环的做的题?
提供一个优化:只循环到sqrt(n),找到能整除的数时把除出来的商也存起来,循环完倒序输出。记得判断一下n是不是平方数,别重复了。
压到10亿次,有点不超时的希望了,再T的话……加个欧拉筛?我不确定会不会成为负优化……
你可能说的是循环嵌套层数太多了导致算法时间复杂度太大。
缩减时间咋办?当然是优化算法喽,让算法不需要那么多循环嵌套。
一个典型的例子:给定一正整数 n ,找出所有和为 n 的勾股数三元组 (a, b, c) (a < b < c) 。
你很可能直接上三层循环,a 从 1 到 n/3 ,b从 1 到 n/3 ,c 从 1 到 n/3 ,途中做个判断剪个枝。
这样一来你算法的时间复杂度就是 O(n^3) ,搞个 n = 100000 你时间铁定会超。
你想 c = n-a-b ,能少一层循环,时间复杂度成了 O(n^2) 。搞个 n = 10000000,你时间还是有可能超。
这题算法能再简化亿点。考虑到:
a*a + b*b = c*c
a*a = c*c - b*b
a*a = (c+b)*(c-b)
a*a = (n-a)*(n-a-2b)
a*a/(n-a) = n-a-2b
2b = n-a - a*a/(n-a)
b = [(n-a) - a*a/(n-a)] / 2
你把 a 和 n 代进去算出来不是正整数就可以弃了。
现在,你只需要一层循环了。
题主还有可能想问的是循环层数不变,如何减少每层的循环次数。这就要谈到剪枝了。循环过程中,你发现这一支已经不可能满足题意了,就不用再进行下一层循环了,避免不必要的计算。这是剪枝。你甚至可以依据题意调整循环变量的取值范围。
然而剪枝不能改变你算法的时间复杂度。剪枝只能将计算量减少某个常数倍(不过好的剪枝能让计算量减少得非常可观)。
说了这么多,我想表达的是, 想缩减循环次数,关键在于你要有一个不需要那么多次循环的算法 。优化算法可能会用到各种数理知识,所以这其实是你的个人能力问题。
多加练习,你的思维会有很大提升的。