1. 程式人生 > >Aladdin and the Flying Carpet LightOJ 1341

Aladdin and the Flying Carpet LightOJ 1341

題意:給一對數字 a,b ,a是一個長方形的面積,問有多少種整數的邊的組合可以組成面積為a的長方形,要求最短的邊不得小於b
思路:用到了唯一分解定理;主要利用公式: 一個整數n可以表示為若干素數乘積: n = p1^a1 * p2^a2pm^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;
}