数学方法
例1. \(1000=2\times 2\times 2\times 5\times 5\times 5\),从 \(6\) 个数中随便拿出若干个(\(0\sim 6\)),它们的乘积一定是 \(1000\) 的约数,问有多少种取法?这个答案即对应 \(1000\) 的约数个数。
解:使用乘法原理,将操作分为 \(2\) 步:
选定一定数量的 \(2\),个数可以是 \(0,1,2,3\);选法有 \(4\) 种。
选定一定数量的 \(5\),个数可以是 \(0,1,2,3\);选法有 \(4\) 种。
两步骤的方法数的乘积,即为答案:\(4\times 4=16\)。
例2. 求 \(28\) 的约数个数。
解:使用乘法原理,\(28=2^2\times 7\):
选定一定数量的 \(2\),个数可以是 \(0,1,2\);选法有 \(3\) 种。
选定一定数量的 \(7\),个数可以是 \(0,1\);选法有 \(2\) 种。
两步骤的方法数的乘积,即为答案:\(3\times 2=6\)。
例3. 求 \(156\) 的约数个数。
解:\(156=2^2\times 3\times 13\),约数个数为:\(3\times 2\times 2=12\)。
代码
使用循环,依次找到 \(n\) 的每个质因数,求出该质因数有多少种选法,并将 \(n\) 中的这些质因数去掉,直到 \(n\) 为 \(1\)。
为了提高效率,我们在 \(i\ast i>n\) 时退出循环,如果此时 \(n>1\),则 \(n\) 必为素数,否则在之前的 \(i\) 中应该已经被分解了。
for (int i = 2; i*i <= n; ++i) {
if(n % i) continue;
int ct = 1;
while (n%i == 0) n /= i, ++ct;
ans *= ct;
}
if (n > 1) ans <<= 1;