一、题目链接
二、题目分析
(一)算法标签
枚举 约数
(二)解题思路
解法一(TLE):重点:两重循环!每一层从上一层的数开始一直枚举到根号!
解法二(AC):先求出所有约数(128个),再三重循环
(
O
(
12
8
3
)
)
(O(128^3))
(O(1283))暴力枚举。
三、AC代码
解法一(暴力枚举+优化):
(1872ms TLE)
#include <iostream>
#include <cmath>
#include <set>
using namespace std;
typedef long long LL;
int main()
{
LL n = 2021041820210418;
LL sqrt_n = sqrt(n);
LL ans = 0;
for (LL i = 1; i <= sqrt_n; i ++ )
{
if (n % i == 0)
{
LL a = n / i;
LL sqrt_a = sqrt(a);
for (LL j = i; j <= sqrt_a; j ++ )
{
if (a % j == 0)
{
LL k = a / j;
set<LL> s;
if (k >= j)
{
s.insert(i);
s.insert(j);
s.insert(k);
}
LL size = s.size();
if (size == 3) ans += 6;
else if (size == 2) ans += 3;
else ans ++ ;
}
}
}
}
printf("%lld", ans);
return 0;
}
解法二:(790ms AC)
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <set>
using namespace std;
typedef long long LL;
vector<LL> get_divisors(LL n)
{
vector<LL> res;
for (LL i = 1; i <= n / i; i ++ )
{
if (n % i == 0)
{
res.push_back(i);
if (i != n / i) res.push_back(n / i);
}
}
sort(res.begin(), res.end());
return res;
}
int main()
{
LL n = 2021041820210418;
vector<LL> divisors = get_divisors(n);
int m = divisors.size(); // 128
LL sqrt_n = sqrt(n);
LL ans = 0;
for (int i = 0; i < m; i ++ )
{
for (int j = 0; j < m; j ++ )
{
for (int k = 0; k < m; k ++ )
{
if (divisors[i] * divisors[j] * divisors[k] == n)
ans ++ ;
}
}
}
printf("%lld", ans);
return 0;
}