暴力解法会超时:
#include <iostream>
using namespace std;
int n;
void divide(int n)
{
if (n < 2) return ;
for (int i = 2; i <= n; ++ i)
{
if (n % i == 0)
{
int s = 0;
while (n % i == 0)
{
n /= i;
s ++;
}
printf("%d %d\n", i, s);
}
}
}
int main()
{
cin >> n;
while (n --)
{
int x;
cin >> x;
divide(x);
cout << endl;
}
return 0;
}
上述代码需要注意一点:为什么i是从2循环到n呢?不是找质因子嘛?不应该是找所有的质数嘛?
答:i如果是合数的话,合数可以分解成多个质数相乘,而这多个质数一定比i小且都为n的因子,但比i小的数在之前就应该被除掉了,所以i一定是一个质数。(合数会被质数筛掉)
由于n中最多只包含一个大于sqrt(n)的质因子(反证法,如果有两个大于n的质因子,则乘积大于n,矛盾,所以最多只包含一个)
由此,我们可以将时间复杂度由O(n)降低到O(sqrt(n))
#include <iostream>
using namespace std;
int n;
void divide(int n)
{
if (n < 2) return ;
for (int i = 2; i <= n / i; ++ i)
{
if (n % i == 0)
{
int s = 0;
while (n % i == 0)
{
n /= i;
s ++;
}
printf("%d %d\n", i, s);
}
}
if (n > 1) printf("%d %d\n", n, 1);
}
int main()
{
cin >> n;
while (n --)
{
int x;
cin >> x;
divide(x);
cout << endl;
}
return 0;
}