题意:给一对数字 a,b ,a是一个长方形的面积,问有多少种整数的边的组合可以组成面积为a的长方形,要求最短的边不得小于b
思路:用到了唯一分解定理;主要利用公式: 一个整数n可以表示为若干素数乘积: n = p1^a1 * p2^a2…pm^am; 则 n 的正因数的个数可以表示为: num = (a1+1)*(a2+1)…(am+1);这个题求解组成矩形的个数,矩形面积是a,最小的边长是b,num重复求解了两次,所以要num/2,因为是从1开始进行求因数个数,题目是[b,a]之间,所以num-[1,b)中是a的约数个数就是所得解。
AC代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
int prime[maxn];
int book[maxn];
int cnt;
void init()
{
cnt = 0;
memset(book,0,sizeof(book));
for(int i = 2; i <= maxn; i++)
{
if(book[i]==0)
{
prime[cnt++] = i;
for(int j = i + i; j <= maxn; j += i)
{
book[j] = 1;
}
}
}
}
int getf(ll x)
{
int ans = 1;
for(int i = 0; i < cnt&&prime[i]*prime[i] <= x; i++)
{
if(x==1)
break;
int temp = 0;
while(x%prime[i]==0)
{
temp++;
x /= prime[i];
}
ans *= (temp+1);
}
if(x!=1)
ans *= 2;
return ans;
}
int main(void)
{
init();
int t;
cin>>t;
for(int i = 1; i <= t; i++)
{
ll a,b;
cin>>a>>b;
if(b*b>=a)
{
printf("Case %d: %d\n",i,0);
continue;
}
int ans = getf(a);
ans /= 2;
for(int j = 1; j < b; j++)
{
if(a%j==0)
ans--;
}
printf("Case %d: %d\n",i,ans);
}
return 0;
}