链接:https://www.nowcoder.com/acm/contest/90/F
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给定n,求1/x + 1/y = 1/n (x<=y)的解数。(x、y、n均为正整数)
输入描述:
在第一行输入一个正整数T。
接下来有T行,每行输入一个正整数n,请求出符合该方程要求的解数。
(1<=n<=1e9)
输出描述:
输出符合该方程要求的解数。
示例1
输入
3 1 20180101 1000000000
输出1
5 181
思路:
1/x + 1/y = 1/n -> xn + yn - xy = 0 -> xn + yn - xy + n^2 = n^2 ->(x - n)*(y - n) = n^2 所以问题转化为求n^2的两个因数相乘的种类,
所以要先求出n^2的质因数有哪些,并且n^2 = n*n所以n^2的因数和n的因数相同,且个数为n的两倍。
#include <bits/stdc++.h> using namespace std; int num[100]; int main(){ int t; cin >> t; while(t--){ memset(num, 0, sizeof(num)); int n, q = 1; cin >> n; for(int i = 2; i * i <= n; i++){ if(n % i == 0){ while(n % i == 0){ num[q]++; n /= i; } q++; } } // cout << "q: " << q << endl; if(n != 1){ //如果上面的for循环条件是 i * i <= n就要这个; 因为我们是从2开始枚举的,对于一个质数,它本身和1构成了一个 num[q]++; //在那个条件下会被pass的,例如 n = 20时;20 -> 10 -> 5,就会被退出,故最后考虑下退出后的n值,即可,并且 //只会是本身,否则n除以他不为1,会在2到sqrt(n)的遍历时发现的。 q++; } // cout << "q: " << q << endl; for(int i = 0; i < q; i++) num[i] *= 2; //存储n*n因数,相当于两倍的n的因数 int ans = 1; for(int i = 0; i < q; i++) ans *= (num[i] + 1); //每个质因数可以出的个数为:0, 1, 2..num[i], 现在分成两部分,一部分来选的话, //他每个质数可选的个数的乘积即为可选的种类 cout << (ans + 1) / 2 << endl; //由于x,y有大小关系,故满足的情况只有一半,可以相等,加一向上取整 } return 0; }