///hdu1299 Diophantus of Alexandria
1/x+1/y=1/n,給定一個n,滿足條件的x,y有多少對。。
x 、y、n都是正整數,並且 顯然,x >= n , y >= n ,現在假設 y = n +k (k爲正整數) ,那麼帶入公式,可以得出 x = (n*(n+k))/k = n*n/k + n; 由於x 是正整數,現在的關鍵問題就是要求出 n*n/ k 有多少組正整數的可能,顯然,所要求的就是 n*n 因子的個數// 問題已經非常接近答案了,但是最後還有一個問題,n<= 10^9 , 那麼n*n <= 10^18 ,對於一個這麼大的數字怎樣才能求出它因子的個數呢?
命題1: 一個正整數 n 可以用素因子唯一表示爲 p1^r1 * p2^r2 * ... pk^rk (其中 pi 爲素數) , 那麼這個數的因子的個數就是,(r1+1)*(r2+1)*...*(rk+1).
如果一個數字 n = p1^r1 * p2^r2 * ... pk^rk ,那麼 n*n = p1^r1 * p2^r2 * ... pk^rk * p1^r1 * p2^r2 * ... pk^rk ,它的因子的個數就是 (2*r1+1)*(2*r2+1)*...*(2*rk+1).
這個問題就轉化成了求 n <= 10^9 的素因子的問題,只需要先篩選出 sqrt(10^9) 內的素數,然後用n去試除 sqrt(n) 中的每一個即可,當然,n可能會有大於sqrt(n) 的因子呶//. 只試到 sqrt(n),怎麼找出所有的素因子呢,不妨想一想,如果n有大於sqrt(n) 的素因子,它會有幾個,又是多少呢? //(答案。此時除過剩下的n自己就是素數。。T-T
code:
#include<iostream>
#include<cmath>
using namespace std;
//const int MAX=3000000; //Çó[2,MAX]¼äµÄËØÊý
const int MAX=50000;
bool isprime[MAX+1];
int prime[MAX];
int pnum; //ËØÊý±íÔªËØ×ÜÊý
void getprime()
{
int i,j;
memset(isprime,0,sizeof(isprime));
pnum=0;
for (i=2;i<=MAX;i++)
{
if(!isprime[i]) prime[pnum++]=i;
for (j=0; j<pnum &&prime[j]*i<=MAX ; j++)
{
isprime[prime[j]*i] = 1;
if (i%prime[j]==0) break;
}
}
}
int main()
{
int T,n,ca=0,i,ans,up;
getprime();
cin>>T;
while(T--)
{
cin>>n;
printf("Scenario #%d:/n",++ca);
ans=1;
for(i=0;i<pnum;i++)
{
up=sqrt(n*1.0)+1;
if(prime[i]>up)break;
int r=0;
while(n%prime[i]==0)
{
r++;
n/=prime[i];
}
ans*=(r*2+1);
}
if(n>1)ans*=3;
printf("%d/n/n",(ans+1)/2);
} return 0;
}
最終結果要+1再/2,從
1 / 5 + 1 / 20 = 1 / 4
1 / 6 + 1 / 12 = 1 / 4
1 / 8 + 1 / 8 = 1 / 4
可以看出。。
有5,20,6,12,8五個。可以組合成(5+1)/2 = 3種