C - Aladdin and the Flying Carpet LightOJ - 1341
题目链接:https://vjudge.net/contest/70017#problem/C
题目:
据说阿拉丁在获得魔法之光之前必须解开七个谜团才能召唤出一个强大的精灵。在这里,我们关注第一个谜。
阿拉丁即将进入一个神奇的洞穴,由邪恶的巫师领导,他伪装成阿拉丁的叔叔,在入口处发现了一个奇怪的神奇飞毯。有一些奇怪的生物守卫着洞穴的入口。阿拉丁可以跑,但他知道有很高的机会被抓住。所以,他决定使用神奇的飞毯。地毯呈矩形,但不是方形。阿拉丁拿走了地毯,在他的帮助下,他经过了入口。
现在,您将获得地毯的区域和地毯最小可能的长度,您的任务是找到可能的地毯类型。例如,地毯12的面积和地毯的最小可能侧面是2,那么可以有两种类型的地毯,它们的侧面是:{2,6}和{3,4}。
输入
输入以整数T(≤4000)开始,表示测试用例的数量。
每个案例以包含两个整数的行开头:a b(1≤b≤a≤1012)其中a表示地毯的面积,b表示地毯的最小可能面。
产量
对于每种情况,请打印案例编号和可能的地毯数量。
Sample Input
2
10 2
12 2
Sample Output
Case 1: 1
Case 2: 2
思路:每个大于1的自然数均可写为质数的积,这是算术基本原理,先宿主筛打表素数,然后分解求因子个数
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> #include<queue> #include<cmath> #include<map> #include<stack> using namespace std; const int maxn=1e6+1000; int n; int cnt=0; int primes[maxn]; int vis[maxn]; void get_primes() { int m=sqrt(maxn+0.5); for(int i=2;i<=m;i++) { if(!vis[i]) { for(int j=i*i;j<=maxn;j+=i) vis[j]=1; } } for(int i=2;i<=maxn;i++) if(!vis[i]) primes[cnt++]=i; } int main() { int T; int kase=0; get_primes(); scanf("%d",&T); while(T--) { long long a,b; scanf("%lld%lld",&a,&b); long long x=a; if(a<=b*b) {printf("Case %d: 0 ",++kase);continue;} long long ans=1; for(int i=0;i<cnt&&primes[i]*primes[i]<=a;i++) { if(a%primes[i]==0)//是公式中的因子 { long long num=0; while(a%primes[i]==0) { num++;//num即为指数 a/=primes[i]; } ans*=(1+num);//因子个数为(1+a1)(1+a2)(1+a3)*..... } } if(a>1) ans*=2; ans/=2; for(long long i=1;i<b;i++) if(x%i==0) ans--; printf("Case %d: %lld ",++kase,ans); } return 0; }