题目描述如下
题目本身不能一股脑全部用来暴力枚举,那么一定会超时,分情况讨论,找到每种情况的规律,那么基本上就能过了
代码如下:
方法:分情况讨论+枚举+求最小的公倍数:乘积/最大公因数
#include<stdio.h>
int gcd(int a,int b); //取最大公因数的函数
int X[100],Y[100];
int main()
{
int o;scanf("%d",&o);
while(o--)
{
int a,b,c,d;scanf("%d %d %d %d",&a,&b,&c,&d);
int cnt=0;
if(a==1&&c==1) //a和c都为1的情况
{
//也就相当于两个等差数列 首项依次为左边取值全为b的倍数 右边取值全为d的倍数
cnt=1000000000/(b*d/gcd(b,d)); //相关实例见代码最后的举例部分
}
else if(a==1||c==1) //a和c其中一个为1 --q取a为等差数列
{
if(c==1)
{
int t=a,T=b;
a=1;c=t;b=d;d=T; //相当于交换x和y //也就是在一个1的情况下都取左边为等差数列,右边为指数函数数列
}
int y=d;
while(y<=1000000000)
{
//调试 printf("here y=%d\n",y);
if(y%b==0) cnt++;
y=y*c+d;
}
}
else if(a!=1&&c!=1) //a和c都不为1 暴力枚举
{
int x=b,y=d;
int q1=1,q2=1;
while(x<=1000000000)
{
//调试 printf("here x=%d\n",x);
X[q1]=x;
x=x*a+b;
q1++;
}
while(y<=1000000000)
{
//调试 printf("here y=%d\n",y);
Y[q2]=y;
y=y*c+d;
q2++;
}
for(int i=1;i<q1;i++)
{
for(int j=1;j<q2;j++)
{
if(X[i]==Y[j]) cnt++;
}
}
}
printf("%d\n",cnt);
}
return 0;
}
int gcd(int a,int b)
{
int t;
while(b!=0)
{
t=a%b;
a=b;
b=t;
}
return a;
}
/*
//第一种情况 在20范围内 2的等差数列 3的等差数列 按照题意0不考虑
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 20
6 12 18--相等的情况 既是2的倍数又是3的倍数-----找到两者的最小公倍数6 (int)20/6=3
2 4 6 8 10 12 14 16 18 20
4 8 12 16 20
两者最小公倍数4 20/4=5
第二种情况
全判断即可 一边为b的n倍 另一半的取值不考虑,只要%b==0则cnt+1
第三种情况
找出两个数组暴力枚举即可
*/
跑不了判题系统,也不知道有没有哪里错了,但是大体上差不多就是这样写的