HDU 1299 Diophantus of Alexandria
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).
由1/x+1/y=1/n
简化成(x-n)(y-n)=n*n,
很明显,只要能将n*n进行因数分解,
则其解都满足题意。
假设n可写成:
a1^k1 * a2^k2 * a3^k3 * ... * am^km, (1)
其中a1,a2,a3,...am互质,
则n*n的约数为
(2k1+1)(2k2+1)(2k3+1)...(2km+1), (2)
记其积为O,
从而其存在的解的个数为
[O+1]/2,
#include<stdio.h> #include<stdlib.h> int prime( int num[] )//素数筛选 { int hash[20000]={0}; for( int i=3; i<=200; i+=2 ) { if( hash[i/2] ) continue; int x=i<<1; for( int j=i*i; j<40000; j+=x ) hash[j/2]=1; } int count=0; num[++count]=2; for( int i=1; i<20000; i++ ) { if( hash[i]==0 ) num[++count]=(i<<1)+1; } return count; } int res( int num[], int count ,int number ) { int sum=1; for( int i=1; i<=count; i++ ) { if( number==1 ) break; int x=0; while( number%num[i]==0 ) { x++; number/=num[i]; } sum*=(2*x+1); } if( number!=1 ) sum*=3; return sum; } int main() { int n,num[5000],number; int count=prime( num ); scanf( "%d",&n ); for( int i=1; i<=n; i++ ) { scanf( "%d",&number ); printf( "Scenario #%d:\n" ,i); printf( "%d\n",(res( num,count,number )+1)/2 ); puts(""); } return 0; }