[pascal] algorytm wypisujący iloczyny

0

Potrzebuję napisać algorytm, który dla danej liczby n, wypisuje wszystkie możliwe iloczyny
a_1a_2...a_k
takie że a_i są liczbami z przedziału [2,..,n-1] oraz cały iloczyn a_1
...*a_k jest mniejszy bądź równy n...
Proszę o pomoc.

P.S.
@mgr. Dobrowolski:
w poprzednim temacie, który wylądował w koszu za niepoprawną nazwę tematu ( http://4programmers.net/Forum/501648?h=#id501648 ) napisałeś poprawne rozwiązanie - jak wygląda algorytm?

0

Ja się jednak upewnię jaki jest problem. Zgodnie ze sformułowaniem, rozwiązanie dla liczby 6 wygląda tak:
22, 23, 32 (trzy iloczyny)
mgr.dobrowolski napisał
2
2, 2*3 (dwa iloczyny).
Jakiej odpowiedzi oczekujesz ?

0

no tak, nie sprecyzowalem...
przyjmijmy zatem ze iloczyn 23 to to samo co 32 (tak jak napisał mgr.Dobrowolski)

0

Można by rozróżnić i więcej przypadków

f(6)=2 (23, 23) to mam
f(6)=3 (22, 23, 32)
f(6)=4 (2
2, 22, 23, 3*2)
do każdego można dodać n-2 rozwiązania, czyli liczby od 2 do n-1

f(6)=2, kilka wyników:
655360 24994590 56.5
655361 24994594 42.6
655362 24994629 39.3
655363 24994630 42.1
655364 24994633 39.3
(dodałem czas w sekundach, PIII, 1 GHz)
Podać iloczyny do sprawdzenia? :-)

O mam też, f(6)=32] (0)
3] (0)
4] 22, (1)
5] 2
2, (1)
6] 22, 23, 32, (3)
7] 2
2, 23, 32, (3)
8] 22, 222, 23, 24, 32, 42, (6)
9] 2
2, 222, 23, 24, 32, 33, 42, (7)
10] 2
2, 222, 23, 24, 25, 32, 33, 42, 52, (9)
11] 2
2, 222, 23, 24, 25, 32, 33, 42, 52, (9)
12] 2
2, 222, 223, 23, 232, 24, 25, 26, 32, 322, 33, 34, 42, 43, 52, 62, (16)
13] 2
2, 222, 223, 23, 232, 24, 25, 26, 32, 322, 33, 34, 42, 43, 52, 62, (16)
14] 2
2, 222, 223, 23, 232, 24, 25, 26, 27, 32, 322, 33, 34, 42, 43, 52, 62, 7*2, code>Wygląda OK, ale dla większych "n" liczy się znacznie dłużej.20000] 8610352 19.4
20001] 8610364 19.3
20002] 8610376 19.3
20003] 8610378 19.6

Dla porównania f(6)=2<code>20000]   315425 0.5
20001]   315429 0.5
20002]   315433 0.5
20003]   315434 0.5
20004]   315444 0.5

Problem w sumie okazał się dość łatwy (30 wierszy, bez rekurencji), swojego rozwiązania na razie nie podaję, warto spróbować samemu.
Mała podpowiedź <font size="1">Popatrz jak układają się liczby w iloczynach, różnica między f(6)=2, a f(6)=3 jest minimalna (powielam ostatnią liczbę albo dokładam dwójkę), iloczyny buduję w małej tabliczce, wystarczyły mi 33 komórki.</span>

Bogdans, wiedziałem, że się odezwiesz [soczek]

0

Prosiłbym jednak o podanie gotowca: zanim przepisałem ten problem na forum, zastanawiałem sie już dość długo nad rozwiązaniem - bezskutecznie. Są to moje pierwsze kroki w programowaniu i pojęcie "Problem w sumie okazał się dość łatwy" zapewne adekwatnym do mojego stanu wiedzy nie jest :)
Pozdrawiam i dzięki za zainteresowanie

0
uses sysutils;

var
  t:array[1..33] of dword; // bo dword to 2^32-1

procedure pisz(i:dword);
var k:dword;
begin
  if i=1 then exit;
  for k:=1 to i-1 do write(t[k],'*');
  write(t[i],', ');
end;

procedure dziel(n:dword);
var L,i:dword; z:qword; // !!! z ma 64 bity, może być 32 gdy n<32766
begin
  //if n mod (1024*1)=0 then write(^m,n);
  write(n, '] ');
  i:=1; t[i]:=2;  // iloczyn t[1]*t[2]*...*t[i]
  L:=0; // licznik rozwiazan
  z:=2; // z=iloczyn t[1]..t[i]
  while t[1]<n do begin
    if z<=n then begin
      pisz(i);
      if i>1 then L+=1;
      // f(6)=2
      if z*t[i]<=n then begin
        i+=1;
        t[i]:=t[i-1];
        z*=t[i]; {}
      { // a to dla f(6)=3
      if z*2<=n then begin
        i+=1;
        t[i]:=2;
        z*=2;  }
      end else begin
        z:=z div t[i];
        t[i]+=1;
        z*=t[i]
      end;
    end else begin
      z:=z div t[i];
      i-=1;
      z:=z div t[i];
      t[i]+=1;
      z*=t[i];
    end
  end;
  write(' ',L);
end;

var n:dword; czas:double;
begin
  for n:=2 to 18 do begin
    czas:=time;
    dziel(n);
    writeln(' ',(time-czas)*24*60*60:0:1);
  end;
  writeln;
end.
0

Wielkie dzięki

0

A bardzo proszę.
Ale myślałem, że ktoś pokaże inne rozwiązanie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1