我不知道我是否正确使用了不可预测的字。但问题出在这里:
我有一张长度为a和宽度为b的长方形纸。我将继续从它切割正方形,其边等于min(a,b),直到最后一个正方形为单位长度。确定我可以切割的方格数。
这是我的算法:
#include <iostream>
using namespace std;
int main()
{
long long a,b,temp,small,large,res;
cin >> a >> b;
res = 0;
small = min(a,b);
large = a + b - small;
while(small > 0 && small != large)
{
res = res + large/small;
temp = large % small;
large = small;
small = temp;
}
cout << res;
return 0;
}
我很困惑如何在这种情况下计算时间复杂度,因为max(a,b)以非偶数方式减小到1,这取决于a和b的初始值。最好的情况肯定是何时,其中一个或两个已经是1。我猜,最糟糕的情况是两者都是素数。请帮我分析时间复杂度。
答案 0 :(得分:2)
该算法与用于计算最大公约数的欧几里德算法非常相似。回想一下,该算法的工作原理是:
a, b
开始,假设不会丢失a >= b
。如果a == b
则停止。b
和a % b
。现在考虑你的算法。它是相同的,除了它是a - b
。但如果a < 2 * b
,这实际上会做同样的事情。如果是a < k * b
,那么在下一轮中它只会改变b
的倍数,因此在最多k
轮后,它将收敛到a % b
。所以这只是欧几里得算法的一个较慢的版本。
欧几里德算法的时间复杂度非常快 - 因为它是重复除法,所以轮数不超过数字位数。
编辑:要扩展到最后一部分: 为了分析时间复杂度,第一个问题是,它需要多少轮。
一种简单的方法是,如果a
和b
的(二进制)描述中包含n
和m
位数,则不能超过n + m
轮。b
轮。因为,只要b
在给定回合中至少有两个,我们将在该回合中将其中一个数字除以2,因此结果将减少一个数字。如果{{1}}是1,那么这是最后一轮。
第二个问题是,进行一轮比赛需要多长时间。
如果您对“运行时间最多是多数位数”感到满意,那么现在就可以清楚了,因为您可以轻松地在多项式中进行数字除法。
我实际上并不确定最严格的分析是什么。你或许可以做一些双赢的分析以改善这一点,我几乎可以肯定这已被研究过但我不知道参考,对不起。