切换到宽版
  • 5434阅读
  • 0回复

请高手帮帮我解析一下这个程序! [复制链接]

上一主题 下一主题
离线notthesame
 
只看楼主 倒序阅读 0 发表于: 2008-04-10
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.
快速回复
限100 字节
 
上一个 下一个