7.1 最多因子数
写一个程序扫描一定范围内的数,并确定在此范围内约数个数最多的那个数。不幸的是,这个数和给定的范围都比较大,用简单的方法寻找可能需要较多的运行时间。所以请确定你的算法能在几秒内完成最大范围内的扫描。
输入
只有一行,给出扫描的范围,由下界L和上界U确定,满足2<=L<=U<=1000000000.
输出
对于给定的范围,输出该范围内约数个数D最多的数P.若有多个,则输出最小的那个.
请输出"Between L and U,P has a maximum of D diviisors.",其中L,U,P和D的含义同前面
所述.
样例
1000 2000
Between 1000 and 2000,1680 has a maximum of 40 diviisors.
$A+,B-,D-,E-,F-,G+,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X-,Y-}
{$M 65520,0,655360}
const fin = 'divisors.in';
fon = 'divisors.out';
maxprime = 31622;
amount = 3401;
var primes :array [1..amount] of word;
l, u, number :longint;
max :word;
procedure getprimes;
var get :array [2..maxprime] of boolean;
i, j :word;
begin
fillchar(get, sizeof(get), 1);
for i := 2 to maxprime do
if get
then begin
j := i + i;
while j <= maxprime do
begin
get[j] := false;
inc(j, i)
end
end;
j := 0;
for i := 2 to maxprime do
if get
then begin
inc(j);
primes[j] := i
end
end;
procedure try(from, tot :word; num, low, up :longint);
var x, y, n, m, p :longint;
i, j, t :word;
begin
if num >= l
then if (tot > max) or ((tot = max) and (num < number))
then begin
max := tot;
number := num
end;
if (low = up) and (low > num) then try(from, tot * 2, num * low, 1, 1);{这步什么意思???}
for i := from to amount do
if primes > up
then exit
else begin
j := primes;
x := low - 1; y := up; n := num; t := tot; m := 1;{x为什么要减一}
while true do
begin
inc(m); inc(t, tot);
x := x div j; y := y div j;
if x = y then break;
n := n * j;
try(i + 1, t, n, x + 1, y){为什么I要加一????}
end;
m := 1 shl m; if tot < max div m then exit
end
end;
begin
assign(input, fin); reset(input);
assign(output, fon); rewrite(output);
getprimes;
readln(l, u);
if (l = 1) and (u = 1)
then begin
max := 1;
number := 1
end
else begin
max := 2; number := l;
try(1, 1, 1, l, u)
end;
writeln('Between ', l, ' and ', u, ', ', number, ' has a maximum of ', max, ' divisors.');
close(output); close(input)
end.