LightOJ 1341 Aladdin and the Flying Carpet
题意:
输入一个矩形面积,以及矩形边长的最小值,已知矩形不是正方形,求有多少种边长组合。
思路:
转化一下就是求面积的所有正约数个数的一半,然后去掉有边长短于最小值以及正方形的情况就是最后答案。
至于求约数个数,由算术基本定理可知:
n=pa11pa22...pakk那么,约数个数=(a1+1)(a2+1)...(ak+1)
.
代码:
/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
using namespace std;
#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define pr( x ) cout << #x << " = " << x << endl
#define pri( x ) cout << #x << " = " << x << " "
#define test( t ) int t ; cin >> t ; int kase = 1 ; while( t-- )
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;
const int maxn = 1e6 + 47;
bool noprime[maxn + 5] ;
vector<int>p ;
int sieve(){
cls( noprime ) ;
p.clear();
for( int i = 2 ; i*i <= maxn ; i++ )
if( !noprime[i] )
for( int j = i * i ; j <= maxn ; j += i )
noprime[j] = true ;
for( int i = 2 ; i <= maxn ; i++ )
if( !noprime[i] ) p.pb( i ) ;
return p.size() ;
}
int calc( lint n , lint B , int len ){
lint res = 1 , tmp = n ;
int i = 0 ;
while( p[i] * p[i] <= n && i < len ) {
lint cnt = 0 ;
if( n % p[i] == 0 ){
while( n % p[i] == 0 ){
n /= p[i] ;
cnt++ ;
}
}
res *= cnt + 1 ;
i++ ;
}
if( n > 1 ){
res <<= 1 ;
}
res >>= 1 ;
n = tmp ;
for( int i = 1 ; i < B ; i++ )
if( n % i == 0 ) res-- ;
return res ;
}
int main(){
int len = sieve() ;
test( t ){
lint a , b ;
scanf( "%lld%lld" , &a , &b ) ;
lint ans ;
if( b * b >= a ){
ans = 0 ;
}
else
ans = calc( a , b , len ) ;
printf( "Case %d: %lld\n" , kase++ , ans ) ;
}
return 0;
}