Aladdin and the Flying Carpet LightOJ 1341
阿新 • • 發佈:2018-11-12
題意:給一對數字 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; }