假如a与b的最大公因数是c,我们把它们分解质因数,将a分解后的结果中含有素数p的个数记为an,将b分解后的结果中含有素数p的个数记为bn,将c分解后的结果中含有素数p的个数记为cn。
如果an=cn,那么bn只要大于cn大可随意取值
如果an>cn,那么bn必须等于cn(自己思考)
如果an<cn,那么这游戏没法玩了,直接输出0退出程序。
假如a与b的最小公倍数是c,我们把它们分解质因数,将a分解后的结果中含有素数p的个数记为an,将b分解后的结果中含有素数p的个数记为bn,将c分解后的结果中含有素数p的个数记为cn。
如果an=cn,那么bn只要小于cn并大于等于0,大可随意取值
如果an<cn,那么bn必须等于cn(自己思考)
如果an>cn,那么这游戏没法玩了,直接输出0退出程序。
那么,如果上述两项讨论中均出现an=cn的情况,我们就可以发现,bn只能取cn(第一项讨论中的)~cn(第二项讨论中的)之间的数。
将情况组合(这里直接相乘)即为解
#include<iostream>
#include<cstdio>
using namespace std;
int prime[5000]={99999999,2,3,5,7};
int primenum=4;
int n,a0,a1,b0,b1;
int result;
void work(int p)
{
int a0n=0,a1n=0,b0n=0,b1n=0;
while(a0%p==0){a0n++;a0/=p;}
while(a1%p==0){a1n++;a1/=p;}
while(b0%p==0){b0n++;b0/=p;}
while(b1%p==0){b1n++;b1/=p;}
if((a0n<a1n)||(b0n>b1n))
{
result=0;
return;
}
if((a0n==a1n)&&(b0n==b1n))
{
if(a1n<=b1n) result*=(b1n-a1n)+1; else result=0;
return;
}
if(((a0n==a1n)&&(b0n<b1n))||((a0n>a1n)&&(b0n==b1n)))
{
if(a1n<=b1n) result*=1; else result=0;
return;
}
if((b0n<b1n)&&(a0n>a1n))
{
if(b1n==a1n) result*=1;else result=0;
return;
}
}
int main()
{
int i,j;
for(i=11;i<45000;i++)
{
for(j=1;((j<=prime[0])&&(prime[j]*prime[j]<=i)&&(i%prime[j]));j++);
if(prime[j]*prime[j]>i || j>prime[0])
{
primenum++;
prime[primenum]=i;
}
}
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a0>>a1>>b0>>b1;
result=1;
for(j=1;j<=4000;j++)
work(prime[j]);
if(a0>1)
work(a0);
else
if((b1>1)&&(b1!=a0))
work(b1);
cout<<result<<endl;
}
return 0;
}
原文:https://www.cnblogs.com/ainiyuling/p/11581870.html