Case 1: 1
Case 2: 2
题目大意:给出矩形面积ab,和组成该矩形的边的最小值,问这种面积为ab的矩形有几种
比如样例12 2,矩形面积为12,组成这样矩形的最小边为2,共有2种这样的矩形(2, 6),(3, 4)(这些边都大于或等于2,其中(2,6)和(6,2)是同一种)
这道题用到了唯一分解定理:N = p1^a1*p2^a2*p3^a3* ... *pn^an(其中p1、p2、... pn为N的因子,a1、a2、... 、an分别为因子的指数)
N的因子个数 M = (1 + a1)*(1 + a2)*(1 + a3)*...*(1 + an);
用唯一分解定理求出ab的因子个数,但题要求的是满足条件的因子对数,所以最终所求的因子个数需要除以2,然后再将不满足的减去
该题要用到筛选素数来缩短时间(减少循环次数)来防止TLE
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
int prime[N], k;
bool Isprime[N];
void Prime()
{
k = 0;
memset(Isprime, true, sizeof(Isprime));
Isprime[1] = false;
for(int i = 2 ; i < N ; i++)
{
if(Isprime[i])
{
prime[k++] = i;
for(int j = 2 ; i * j < N ; j++)
Isprime[i * j] = false;
}
}
}//素数筛选
ll solve(ll n)
{
ll ans = 0, sum = 1;
for(ll i = 0 ; i < k && prime[i] * prime[i] <= n ; i++)
{
if(n % prime[i] == 0)
{
ans = 0;
while(n % prime[i] == 0)
{
ans++;
n /= prime[i];
}
sum *= (1 + ans);
}
}
if(n > 1)
sum *= 2;
return sum;
}//找n的因子个数
int main()
{
Prime();
int t, x = 0;
ll ab, a, num;
scanf("%d", &t);
while(t--)
{
x++;
scanf("%lld%lld", &ab, &a);
if(ab < a * a)
{
printf("Case %d: 0\n", x);
continue;
}
num = solve(ab);
num /= 2;
for(ll i = 1 ; i < a ; i++)
if(ab % i == 0)
num--;//将边小于a的情况减去
printf("Case %d: %lld\n", x, num);
}
return 0;
}