算法:数学+搜索
本题的做法有很多,这里介绍两种:
1.首先我们知道GCD最小为a1,因为要求的使GCD等于a1,而LCM为b1,因为要求的使LCM为b1。
因此我们在知道了范围以后就可以直接枚举了,从a1到b1,这样的话能得到50分。。。
2.设:
A=p1^a1+p2^a2+p3^a3+...
B=p1^b1+p2^b2+p3^b3+...
则LCD=p1^(min(a1,b1))+p2^(min(a2,b2))+p3^(min(a3,b3))+...
LCM=p1^(max(a1,b1))+p2^(max(a2,b2))+p3^(max(a3,b3))+...
本题的做法有很多,这里介绍两种:
1.首先我们知道GCD最小为a1,因为要求的使GCD等于a1,而LCM为b1,因为要求的使LCM为b1。
因此我们在知道了范围以后就可以直接枚举了,从a1到b1,这样的话能得到50分。。。
2.设:
A=p1^a1+p2^a2+p3^a3+...
B=p1^b1+p2^b2+p3^b3+...
则LCD=p1^(min(a1,b1))+p2^(min(a2,b2))+p3^(min(a3,b3))+...
LCM=p1^(max(a1,b1))+p2^(max(a2,b2))+p3^(max(a3,b3))+...
分解质因数的方法,将b1分解质因数,然后进行搜索,搜索时必须要选择所搜出的质因数的种类个,对于搜索出的所有情况注意验证累加就可以了。
program son;
const
maxn=1000;
var
n,m,tot,ii,jj,a0,a1,b0,b1,ans:longint;
p,x,c:array [0..maxn] of longint;
function gcd(a,b:longint):longint;
begin
if b=0 then exit(a) else exit(gcd(b,a mod b));
end;
procedure dfs(i,sum:longint);
var
j,max:longint;
begin
if i>m then{不懂这里为什么要大于m才行。}
begin
inc(tot);
p[tot]:=sum;
exit;
end;
max:=sum;
dfs(i+1,max);{每个质因数可以不选,可以选一个,也可以选多个。}
for j:=1 to c[i] do
begin
max:=max*x[i];
dfs(i+1,max);
end;
end;
procedure work(q:longint);{分解质因数过程。}
var
i:longint;
begin
i:=2;
while i<=sqrt(q) do
begin
if q mod i=0 then
begin
inc(m);
x[m]:=i;
c[m]:=0;
while q mod i=0 do
begin
inc(c[m]);
q:=q div i;
end;
end;
inc(i);
end;
if q<>1 then
begin
inc(m);
x[m]:=q;
c[m]:=1;
end;
dfs(1,1);
end;
begin
assign(input,'son.in'); reset(input);
assign(output,'son.out'); rewrite(output);
readln(n);
for ii:=1 to n do
begin
readln(a0,a1,b0,b1);
fillchar(p,sizeof(p),0);
fillchar(x,sizeof(x),0);
fillchar(c,sizeof(c),0);
m:=0;
tot:=0;
ans:=0;
work(b1);
for jj:=1 to tot do if (gcd(p[jj],a0)=a1) and ((p[jj] div gcd(p[jj],b0))*b0=b1) then inc(ans);{累计过程。}
writeln(ans);
end;
close(input); close(output);
end.
本文介绍了一种结合数学和搜索算法解决最大公约数(GCD)及最小公倍数(LCM)问题的方法。通过分解质因数并进行搜索,找到满足特定GCD和LCM条件的数对。文章提供了详细的算法步骤和实现代码。
672

被折叠的 条评论
为什么被折叠?



