27-1/x+1/y=1/n

链接:https://www.nowcoder.com/acm/contest/90/F
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制: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;
} 

  




原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/8644257.html